前言:今天給大家給大家講解的是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 原理說明
- 需求:是否可以實現服務的自動發現和註冊
圖很醜,沒有大神級的畫得好看,將就着看吧。
圖示解析:
- 當服務提供者啓動時,會將服務數據保存到zk中。
- 當zk接收用戶服務信息之後,會將數據保存到服務列表中。
- 當消費者啓動時,先連接zk獲取zk的服務列表。
- 之後緩存到本地,方便下次訪問。
- 消費者接收用戶的請求時,根據負載均衡策略,實現請求的發送,並且獲取服務端的數據(RPC)。
- 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 項目搭建
- 創建 dubbo-jt 爲父類項目(Maven Project)
- 在dubbo-jt下,創建dubbo-jt-demo-consumer/interface/provider/provider2 四個子級項目(Maven Module)
- 在此之前你可以創建dubbo的工作空間
- 如果前三步做成,你將會看到
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("我是第二個服務提供者");