一. Dubbo概述
1. 什麼是Dubbo?
一款分佈式服務框架,高性能和透明化的RPC遠程服務調用方案,SOA服務治理方案。
每天爲2千多個服務提供大於30億次訪問量支持,並被廣泛應用於阿里巴巴集團的各成員站點以及別的公司的業務中。
2. Dubbo優缺點
優點: ① 透明化的遠程方法調用 像調用本地方法一樣調用遠程方法;只需簡單配置,沒有任何API侵入。 ② 軟負載均衡及容錯機制 可在內網替代nginx lvs等硬件負載均衡器。 ③ 服務註冊中心自動註冊 & 配置管理 不需要寫死服務提供者地址,註冊中心基於接口名自動查詢提供者ip。 使用類似zookeeper等分佈式協調服務作爲服務註冊中心,可以將絕大部分項目配置移入zookeeper集羣。 ④ 服務接口監控與治理 -Dubbo-admin與Dubbo-monitor提供了完善的服務接口管理與監控功能,針對不同應用的不同接口,可以進行 多版本,多協議,多註冊中心管理。
缺點: 只支持Java語言
3. Dubbo架構原理
角色區分:
① Provider: 暴露服務的服務提供方(生產者)
② Consumer: 調用遠程服務的服務消費方(消費者)
③ Registry: 服務註冊與發現的註冊中心(zookeeper,redis等)
④ Monitor: 統計服務的調用次數和調用時間的監控中心(dubbo-admin)
調用流程:
0>服務容器負責啓動,加載,運行服務提供者。
1>服務提供者在啓動時,向註冊中心註冊自己提供的服務。
2>服務消費者在啓動時,向註冊中心訂閱自己所需的服務。
3>註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者
4>服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用
5>服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心
4. Dubbo與SpringCloud的區別
相同點:SpringCloud 和Dubbo可以實現RPC遠程調用框架,可以實現服務治理。
不同點:SpringCloud是一套目前比較網站微服務框架了,整合了分佈式常用解決方案遇到了問題註冊中心Eureka、負載均衡器Ribbon ,客戶端調用工具Rest和Feign,分佈式配置中心Config,服務保護Hystrix,網關Zuul Gateway ,服務鏈路Zipkin,消息總線Bus等。 從架構上分析,Dubbo內部實現功能沒有SpringCloud強大,只是實現服務治理,缺少分佈式配置中心、網關、鏈路、總線等,如果需要用到這些組件,需要整合其他框架。從更新迭代速度分析,Dubbo目前更新速度沒有SpringCloud快,到SpringCloud2.0後SpringCloud會越來完善和穩定。從開發背景角度分析,Dubbo的開發背景是阿里巴巴, 在中國也推出了非常多的優秀的開源框架,但是在SpringCloud的背景是Spring家族,Spring是專注於企業級開源框架開發,在中國,或者在整個世界上Spring框架都應用的非常廣泛。所有相對來說SpringCloud的背景比Dubbo更加強大。
二. Dubbo實戰(SpringBoot整合Dubbo)
準備工作:本地需要安裝zookeeper,並用ZooInspector工具連接成功。
項目結構圖:(基於maven的聚合項目)
dubbo-parent爲根目錄,pom類型;dubbo-api-service爲服務接口目錄,其下的dubbo-member-service爲會員接口服務;dubbo-member-service-impl,dubbo-order-service-impl爲別爲會員,訂單接口實現(springboot項目)。
本案例即爲模擬訂單服務調用會員服務,下面開始搭建:
首先配置各個服務pom依賴關係:
dubbo-parent
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>dubbo-parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>dubbo-api-service</module>
<module>dubbo-member-service-impl</module>
<module>dubbo-order-service-impl</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<curator-framework.version>4.0.1</curator-framework.version>
<zookeeper.version>3.4.13</zookeeper.version>
<dubbo.starter.version>0.2.0</dubbo.starter.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.starter.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator-framework.version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
dubbo-api-service
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-service</artifactId>
<packaging>pom</packaging>
<modules>
<module>dubbo-member-service</module>
</modules>
</project>
dubbo-member-service
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-service</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-member-service</artifactId>
</project>
dubbo-member-service-impl
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-member-service-impl</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-member-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
dubbo-order-service-impl
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-order-service-impl</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-member-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
在會員服務接口dubbo-member-service新建MemberService
package com.example.service;
public interface MemberService {
String getUser(Long userId);
}
dubbo-member-service-impl新建MemberServiceImpl,實現MemberService
package com.example.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.example.service.MemberService;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @Service 發佈服務,表示將該接口註冊到註冊中心上去
* @author zhaobin
* @date 2019/11/26
*/
@Service
public class MemberServiceImpl implements MemberService {
public String getUser(@RequestParam Long userId) {
System.out.println("會員服務實現,userId爲:" + userId);
return "會員服務實現,userId爲:" + userId;
}
// dubbo服務發佈的時候,採用dubbo註解方式,使用@Service註解進行注入,注意是dubbo提供的@Service註解
}
會員實現啓動類:
package com.example;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @EnableDubbo 開啓Dubbo服務
* @author zhaobin
* @date 2019/11/26
*/
@EnableDubbo
@SpringBootApplication
public class AppMember {
public static void main(String[] args) {
SpringApplication.run(AppMember.class, args);
}
}
會員實現配置類
server:
port: 8081
dubbo:
application:
name: member
protocol:
# 使用dubbo協議
name: dubbo
# 發佈dubbo端口號爲20880
port: 20880
registry:
address: zookeeper://127.0.0.1:2181
scan:
# dubbo實現類掃包範圍
base-packages: com.example.impl
dubbo-order-service-impl新建OrderController
package com.example.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.example.service.MemberService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @Reference Dubbo提供 - 調用服務
*/
@RestController
public class OrderController {
@Reference // 不能用@Autowired註解
private MemberService memberService;
@RequestMapping("/orderToMember")
public String orderToMember(@RequestParam Long userId) {
System.out.println("訂單服務實現");
return memberService.getUser(userId);
}
}
訂單實現啓動類
package com.example;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo
@SpringBootApplication
public class AppOrder {
public static void main(String[] args) {
SpringApplication.run(AppOrder.class, args);
}
}
訂單實現配置類
server:
port: 8082
dubbo:
application:
name: order
# protocol: # 不註冊服務,不用加
# name: dubbo
# port: 20880
registry:
address: zookeeper://localhost:2181
consumer:
timeout: 5000
至此,項目環境搭建完畢,分別啓動member-impl和order-impl,可以看到zk客戶端註冊了生產者和消費者的信息
此時,訂單服務訪問接口 http://localhost:8082/orderToMember,可以成功從會員服務拿到信息
三. 搭建DubboAdmin監控平臺
下載dubbo-admin.zip,解壓到tomcat的webapps目錄下,並修改dubbo.properties的連接地址即可,啓動tomcat:
可以看到服務的信息,以及調用鏈;DubboAdmin底層實現連接ZooKeeper信息,進行解析轉化成頁面進行展示。
【小結】:Dubbo在zookeeper註冊採用持久節點+臨時節點,下圖紅色箭頭的爲持久節點,因爲接口一般都不會變,藍色箭頭爲臨時節點,當項目停了,下面的子文件就不存在了,見右圖。