微服務架構Dubbo之原理講解及利用zookeeper作爲註冊中心進行高可用測試

前言:今天給大家給大家講解的是Dubbp的調用原理,以及一個demo測試向大家展示Dubbo的運行過程。在前面一文中,給大家講到了—Dubbo之Zookeeper安裝測試和Zookeeper集羣的搭建 ,在其中已經給大家講到了Zookeeper集羣的搭建,今天我們也要用到該集羣,如果沒有安裝的,請先行安裝,再看下文!!


1.Dubbo原理

1.1 高性能Java RPC框架

Apache Dubbo 是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。

在這裏插入圖片描述

1.2 Dubbo特性

  • 面向接口代理的高性能RPC調用
  • 服務自動註冊與發現
  • 運行期流量調度
  • 智能負載均衡
  • 高度可擴展能力
  • 可視化的服務治理與運維

以上幾點接來源於dubbo的官網:http://dubbo.apache.org/zh-cn/

1.3 Dubbo工作原理

1.3.1 Dubbo高可用測試

  • 測試1:將後臺提供者宕機一臺,檢查是否影響消費者調用。

不影響 註冊中心實現心跳檢測機制. 即使沒有註冊中心,又要有提供者就可以正常訪問

  • 測試2: 將zookeeper宕機一臺,檢查是否影響用戶使用。

不影響 因爲zk搭建了集羣.可以實現高可用

  • 測試3: 將zookeeper集羣全部宕機,檢查是否影響用戶使用。

不影響. 因爲消費者將zk註冊中心的數據,已經保存到本地(消費者的內存中),所以不收影響

1.3.2 Dubbo通訊問題

核心:微服務通信一般都是靠RPC(統稱)
dubbo中的RPC基於dubbo的協議規範

在這裏插入圖片描述

1.4 Dubbo調用原理

1.4.1 原理說明

  • 需求:是否可以實現服務的自動發現和註冊

在這裏插入圖片描述

圖很醜,沒有大神級的畫得好看,將就着看吧。
圖示解析

  1. 當服務提供者啓動時,會將服務數據保存到zk中。
  2. 當zk接收用戶服務信息之後,會將數據保存到服務列表中。
  3. 當消費者啓動時,先連接zk獲取zk的服務列表。
  4. 之後緩存到本地,方便下次訪問。
  5. 消費者接收用戶的請求時,根據負載均衡策略,實現請求的發送,並且獲取服務端的數據(RPC)。
  6. Zk實時的心跳檢測,如果後臺服務器宕機,則需要更新自己的服務列表,同時廣播給全部的客戶端。

1.5 Dubbo入門案例

1.5.0 導入數據庫

CREATE DATABASE /*!32312 IF NOT EXISTS*/`jtdb` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `jtdb`;

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(40) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(40) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `cc` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`id`,`name`,`age`,`sex`) values (1,'黑熊精',4000,'男'),(2,'鯉魚精',5000,'男'),(3,'金角大王',3000,'男'),(4,'銀角大王',4000,'男'),(5,'唐僧',30,'男'),(6,'悟空',501,'男'),(7,'白龍驢',2000,'男'),(8,'八戒',502,'男'),(9,'沙悟淨',503,'男'),(11,'小喬',17,'女'),(12,'貂蟬',18,'女'),(16,'黃月英',18,'女'),(17,'孫尚香',18,'女'),(18,'甄姬c',20,'女'),(21,'孫尚香D',18,'女'),(22,'劉備',40,'男'),(23,'陸遜',33,'男'),(24,'陸遜',33,'男'),(25,'關羽',40,'男'),(27,'阿科',20,'女'),(31,'王昭君',19,'女'),(38,'貂蟬',18,'女'),(39,'西施',18,'女'),(40,'嚴真煌',16,'女'),(41,'白骨精',18,'女'),(43,'小喬',19,'男'),(44,'大喬',19,'女'),(46,'不知火舞',18,'女'),(49,'小蘭蘭',18,'男'),(50,'柳鵬林',18,'男'),(51,'妲己',18,'男'),(52,'如花',17,'男');

1.5.1 項目搭建

  1. 創建 dubbo-jt 爲父類項目(Maven Project)
  2. 在dubbo-jt下,創建dubbo-jt-demo-consumer/interface/provider/provider2 四個子級項目(Maven Module)
  3. 在此之前你可以創建dubbo的工作空間

在這裏插入圖片描述
在這裏插入圖片描述

  1. 如果前三步做成,你將會看到

在這裏插入圖片描述

1.5.2 導入pom文件 – 最後一個dependency就是dubbo的配置

dubbo-jt的pom文件
<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.5.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<java.version>1.8</java.version>
		<!--添加maven插件 -->
		<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
	</properties>

	<dependencies>
		<!--springBoot動態的引入springMVC全部的配置 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<!--引入測試類 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<!--添加屬性注入依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>

		<!--支持熱部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
			<version>1.2.8.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>

		<!--引入插件lombok 自動的set/get/構造方法插件 -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

		<!--引入數據庫驅動 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!--引入druid數據源 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.12</version>
		</dependency>

		<!--spring整合mybatis-plus -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.0.6</version>
		</dependency>

		<!--spring整合redis -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
		</dependency>

		<!--springBoot整合JSP添加依賴 -->
		<!--servlet依賴 注意與eureka整合時的問題 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
		</dependency>

		<!--jstl依賴 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
		</dependency>

		<!--使jsp頁面生效 -->
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
		</dependency>

		<!--添加httpClient jar包 -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
		</dependency>
		
		<!--引入dubbo配置 -->
		<dependency>
			<groupId>com.alibaba.boot</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
			<version>0.2.0</version>
		</dependency>	
	</dependencies>
	<modules>
		<module>dobbo-jt-demo-interface</module>
		<module>dubbo-jt-demo-provider</module>
		<module>dubbo-jt-demo-consumer</module>
		<module>dubbo-jt-demo-provider2</module>
	</modules>
dubbo-jt-demo-consumer --編輯pom文件(消費者)
  <parent>
    <groupId>com.jt.dubbo</groupId>
    <artifactId>dubbo-jt</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>dubbo-jt-demo-consumer</artifactId>
  <dependencies>
  	<dependency>
  		<groupId>com.jt.dubbo</groupId>
  		<artifactId>dubbo-jt-demo-interface</artifactId>
  		<version>0.0.1-SNAPSHOT</version>
  	</dependency>
  </dependencies>
dubbo-jt-demo-provider/provider2 --編輯pom文件(提供者)
  <parent>
    <groupId>com.jt.dubbo</groupId>
    <artifactId>dubbo-jt</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>dubbo-jt-demo-provider</artifactId>
  <dependencies>
  	<dependency>
  		<groupId>com.jt.dubbo</groupId>
  		<artifactId>dubbo-jt-demo-interface</artifactId>
  		<version>0.0.1-SNAPSHOT</version>
  	</dependency>
  </dependencies>

1.5.3 編寫intrface (第三方接口)

在com.jt.dubbo.pojo中,創建User實體類
@Data
@Accessors(chain=true)
@TableName
public class User implements Serializable{
	//dubbo協議傳輸的對象必須序列化
	private static final long serialVersionUID = 1L;
	@TableId(type=IdType.AUTO)
	private Integer id;
	private String name;
	private Integer age;
	private String sex;
}
在com.jt.dubbo.service中創建UserService
public interface UserService {
	
	//查詢全部用戶信息
	List<User> findAll();
	//導入數據庫
	@Transactional
	void saveUser(User user);
}

1.5.4 編寫consumer(消費者)

在com.jt下編寫啓動類SpringBoot_Run
//springBoot啓動時排除數據源啓動項
@SpringBootApplication(exclude=DataSourceAutoConfiguration.class)
public class SpringBoot_Run {
	
	public static void main(String[] args) {
		
		SpringApplication.run(SpringBoot_Run.class, args);
	}
}
在resources下編輯application.yml 文件
server:
  port: 9001
dubbo:
  scan:
    basePackages: com.jt
  application:
    name: consumer-user    #消費者名稱
  registry:
    address: zookeeper://192.168.126.166:2181?backup=192.168.126.166:2182,192.168.126.166:2183
在com.jt.dubbo.controller下創建UserController類
@RestController
public class UserController {
	
	@Reference(timeout=3000,check=true)
	//@Autowired   //從spring容器中進行注入
	private UserService userService;    //注入第三方管理的service
	
	@RequestMapping("/findAll")
	public List<User> findAll(){
		
		return userService.findAll();
	}
	
	@RequestMapping("/saveUser/{name}/{age}/{sex}")
	public String saveUser(User user) {
		
		userService.saveUser(user);
		return "用戶入庫成功!!!";
	}
}

1.5.5 編寫provider(提供者1)

啓動類SpringBoot_Run
@SpringBootApplication
@MapperScan("com.jt.dubbo.mapper")
public class SpringBoot_Run {
	
	public static void main(String[] args) {
		
		SpringApplication.run(SpringBoot_Run.class, args);
	}
}
application.yml文件編寫
server:
  port: 9000  #定義端口

spring:
  datasource:
    #引入druid數據源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root
    
dubbo:
  scan:
    basePackages: com.jt      #指定dubbo包路徑
  application:
    name: provider-user       #指定服務名稱(必須指定)
  registry:
    address: zookeeper://192.168.126.166:2181?backup=192.168.126.166:2182,192.168.126.166:2183
  protocol:     #指定協議
    name: dubbo      #使用dubbo協議(tcp-ip) web-controller直接調用sso-service
    port: 20880      #服務鏈接時的端口

      
mybatis-plus:
  type-aliases-package: com.jt.dubbo.pojo       #配置別名包路徑
  mapper-locations: classpath:/mybatis/mappers/*.xml  #添加mapper映射文件
  configuration:
    map-underscore-to-camel-case: true                #開啓駝峯映射規則
在resources/mybatis/mappers下創建UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.dubbo.mapper.UserMapper">

</mapper>
在com.jt.dubbo.mapper下編寫UserMapper接口(使用的是MybatisPlus)
public interface UserMapper extends BaseMapper<User>{
	
}
在com.jt.dubbo.service下創建UserServiceImpl類
@Service(timeout=3000)	//3秒超時	
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserMapper userMapper;
	@Override
	public List<User> findAll() {
		
		System.out.println("我是第一個服務的提供者");
		return userMapper.selectList(null);
	}
	
	@Override
	public void saveUser(User user) {
		
		userMapper.insert(user);
	}

}

1.5.6 provider2 (提供者2)

與provider相比,

  • 更改application.yml中的server:port:9003
  • 以及更改dubbo的端口號爲20882因爲每個服務都應該有自己獨立的端口
  • UserServiceImpl中的—System.out.println("我是第二個服務提供者");

1.6 測試效果

1.6.0 開啓zk集羣

在這裏插入圖片描述

1.6.1 開啓consumer/provider/provider2

1.6.2 搜索 localhost:9001/findAll 數據顯示,表示查詢成功

在這裏插入圖片描述

1.6.3 在後臺顯示provider/provider2均可被調用

在這裏插入圖片描述

在這裏插入圖片描述

1.6.4 將zk集羣全部宕機 – 後臺會一直報如錯誤

在這裏插入圖片描述

1.6.5 即使所有集羣被宕機,也不會影響消費者的使用

因爲 消費者啓動時已經將服務信息緩存到本地,故不會影響
亦或者有一個提供者宕機了,用戶依然可以正常訪問,且本地服務列表還會動態更新,只不過該程序將處於高位運行狀態之下。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章