Dubbo的基本使用
1、Dubbo的基本介紹
Dubbo 是阿里巴巴公司開(kāi)源的一個(gè)高性能、輕量級(jí)的 Java RPC 框架。 它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)。
1.1、基本概念

- 服務(wù)提供者(Provider):暴露服務(wù)的服務(wù)提供方,服務(wù)提供者在啟動(dòng)時(shí),向注冊(cè)中心注冊(cè)自己提供的服務(wù)。
- 服務(wù)消費(fèi)者(Consumer): 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方,服務(wù)消費(fèi)者在啟動(dòng)時(shí),向注冊(cè)中心訂閱自己所需的服務(wù),服務(wù)消費(fèi)者,從提供者地址列表中,基于軟負(fù)載均衡算法,選一臺(tái)提供者進(jìn)行調(diào)用,如果調(diào)用失敗,再選另一臺(tái)調(diào)用。
- 注冊(cè)中心(Registry):注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給消費(fèi)者
- 監(jiān)控中心(Monitor):服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心
調(diào)用關(guān)系說(shuō)明:
- 服務(wù)容器負(fù)責(zé)啟動(dòng),加載,運(yùn)行服務(wù)提供者。
- 服務(wù)提供者在啟動(dòng)時(shí),向注冊(cè)中心注冊(cè)自己提供的服務(wù)。
- 服務(wù)消費(fèi)者在啟動(dòng)時(shí),向注冊(cè)中心訂閱自己所需的服務(wù)。
- 注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給消費(fèi)者。
- 服務(wù)消費(fèi)者,從提供者地址列表中,基于軟負(fù)載均衡算法,選一臺(tái)提供者進(jìn)行調(diào)用,如果調(diào)用失敗,再選另一臺(tái)調(diào)用。
2、zookeeper(注冊(cè)中心)
Zookeeper是一個(gè)高性能的,分布式的,開(kāi)放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),簡(jiǎn)稱(chēng)zk。
2.1、zookeeper 下載
下載可在官網(wǎng)下載,如 3.4.11 地址參考:https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/
2.2、zookeper安裝使用(window版)
ZooKeeper服務(wù)器是用Java創(chuàng)建的,它運(yùn)行在JVM之上。需要安裝JDK 7或更高版本。

zookeeper 下載后直接解壓即可。在bin文件下,直接通過(guò)命令行執(zhí)行 zkServer.cmd 即為啟動(dòng) zookeeper。
第一次啟動(dòng)時(shí)可能會(huì)有報(bào)錯(cuò),如下:

此時(shí)只需在 conf 目錄下將 zoo_sample.cfg 文件復(fù)制一份,將名字改為 zoo.cfg 即可。打開(kāi) zoo.cfg 文件,可以看到內(nèi)容如下:

可以將 dataDir 路徑修改為我們想要保存文件的路徑,如:../data,然后建立相應(yīng)的目錄即可。
再次啟動(dòng) zookeeper,可以看到可正常啟動(dòng),輸出如下:

可以運(yùn)行 zkCli.cmd 連接到zookeeper的服務(wù)器,如下:

2.3、zookeper安裝使用(Linux版)
ZooKeeper服務(wù)器是用Java創(chuàng)建的,它運(yùn)行在JVM之上。需要安裝JDK 7或更高版本。

將下載的ZooKeeper放到/opt/ZooKeeper目錄下:
#打開(kāi) opt目錄 cd /opt #創(chuàng)建zooKeeper目錄 mkdir zooKeeper #將zookeeper安裝包移動(dòng)到 /opt/zooKeeper mv apache-zookeeper-3.5.6-bin.tar.gz /opt/zookeeper/
將tar包解壓到/opt/zookeeper目錄下
tar -zxvf apache-zookeeper-3.5.6-bin.tar.gz
配置zoo.cfg
#進(jìn)入到conf目錄 cd /opt/zooKeeper/apache-zookeeper-3.5.6-bin/conf/ #拷貝 cp zoo_sample.cfg zoo.cfg
修改zoo.cfg
#打開(kāi)目錄 cd /opt/zooKeeper/ #創(chuàng)建zooKeeper存儲(chǔ)目錄 mkdir zkdata #修改zoo.cfg vim /opt/zooKeeper/apache-zookeeper-3.5.6-bin/conf/zoo.cfg
修改存儲(chǔ)目錄:dataDir=/opt/zookeeper/zkdata
啟動(dòng)ZooKeeper
cd /opt/zooKeeper/apache-zookeeper-3.5.6-bin/bin/ #啟動(dòng) ./zkServer.sh start
看到下圖表示ZooKeeper成功啟動(dòng)

2.3.1、查看ZooKeeper狀態(tài)
查看ZooKeeper狀態(tài)
./zkServer.sh status
下圖表示zookeeper啟動(dòng)成功。standalone代表zk沒(méi)有搭建集群,現(xiàn)在是單節(jié)點(diǎn)

下圖表示zookeeper沒(méi)有啟動(dòng)

3、提供者消費(fèi)者示例
(建議參考 3.2、springboot搭建dubbo示例)
3.1、spring搭建dubbo示例
基于以下圖實(shí)現(xiàn)服務(wù) 提供者、消費(fèi)者,即以用戶服務(wù)作為提供者,訂單服務(wù)作為消費(fèi)者。

分別創(chuàng)建 maven 工程 user-service-provider、order-service-consumer,還需要?jiǎng)?chuàng)建一個(gè)專(zhuān)門(mén)用于存服務(wù)接口的工程 dubbo-interface。
提供者工程 user-service-provider 引入以下依賴:(dubbo依賴會(huì)自動(dòng)引入 spring 的相關(guān)依賴),另外需要引入 dubbo-interface 工程。
<dependencies> <!-- 引入dubbo --> <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 注冊(cè)中心使用的是zookeeper,引入操作zookeeper的客戶端 --> <!-- 由于我們使用zookeeper作為注冊(cè)中心,所以需要操作zookeeper dubbo 2.6以前的版本引入zkclient操作zookeeper dubbo 2.6及以后的版本引入curator操作zookeeper 下面兩個(gè)zk客戶端根據(jù)dubbo版本2選1即可 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> </dependencies>
提供者工程添加配置文件 provider.xml,并添加以下配置內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 1、指定當(dāng)前服務(wù)/應(yīng)用的名字(同樣的服務(wù)名字相同,不要和別的服務(wù)同名) --> <dubbo:application name="user-service-provider"></dubbo:application> <!-- 2、指定注冊(cè)中心的位置 --> <!-- <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry> --> <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry> <!-- 3、指定通信規(guī)則(通信協(xié)議?通信端口) --> <dubbo:protocol name="dubbo" port="20882"></dubbo:protocol> <!-- 4、暴露服務(wù) ref:指向服務(wù)的真正的實(shí)現(xiàn)對(duì)象 --> <dubbo:service interface="com.atguigu.gmall.service.UserService" ref="userServiceImpl01" timeout="1000" version="1.0.0"> <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method> </dubbo:service> <!-- 服務(wù)的實(shí)現(xiàn) --> <bean id="userServiceImpl01" class="com.atguigu.gmall.service.impl.UserServiceImpl"></bean> <!--統(tǒng)一設(shè)置服務(wù)提供方的規(guī)則 --> <dubbo:provider timeout="1000"></dubbo:provider> <dubbo:service interface="com.atguigu.gmall.service.UserService" ref="userServiceImpl02" timeout="1000" version="2.0.0"> <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method> </dubbo:service> <bean id="userServiceImpl02" class="com.atguigu.gmall.service.impl.UserServiceImpl2"></bean> <!-- 連接監(jiān)控中心 --> <dubbo:monitor protocol="registry"></dubbo:monitor> </beans>
暴露的服務(wù)的實(shí)現(xiàn)類(lèi) UserServiceImpl、UserServiceImpl2 代碼大概如下:
public class UserServiceImpl2 implements UserService { @Override public List<UserAddress> getUserAddressList(String userId) { System.out.println("UserServiceImpl.....new..."); UserAddress address1 = new UserAddress(1, "北京市昌平區(qū)宏福科技園綜合樓3層", "1", "李老師", "010-56253825", "Y"); UserAddress address2 = new UserAddress(2, "深圳市寶安區(qū)西部硅谷大廈B座3層(深圳分校)", "1", "王老師", "010-56253825", "N"); return Arrays.asList(address1,address2); } }
啟動(dòng)提供者,main 方法如下:
public class MainApplication { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml"); ioc.start(); System.in.read(); } }
啟動(dòng)提供者后可以在管理控制臺(tái)看到注冊(cè)的服務(wù):

在消費(fèi)者工程引入依賴:
<dependencies> <!-- 引入dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 注冊(cè)中心使用的是zookeeper,引入操作zookeeper的客戶端端 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> </dependencies>
消費(fèi)者工程添加配置文件 consumer.xml,并添加以下配置內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <context:component-scan base-package="com.atguigu.gmall.service.impl"></context:component-scan> <dubbo:application name="order-service-consumer"></dubbo:application> <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry> <!-- 配置本地存根--> <!--聲明需要調(diào)用的遠(yuǎn)程服務(wù)的接口;生成遠(yuǎn)程服務(wù)代理 --> <!-- 1)、精確優(yōu)先 (方法級(jí)優(yōu)先,接口級(jí)次之,全局配置再次之) 2)、消費(fèi)者設(shè)置優(yōu)先(如果級(jí)別一樣,則消費(fèi)方優(yōu)先,提供方次之) --> <!-- timeout="0" 默認(rèn)是1000ms--> <!-- retries="":重試次數(shù),不包含第一次調(diào)用,0代表不重試--> <!-- 冪等(設(shè)置重試次數(shù))【查詢、刪除、修改】、非冪等(不能設(shè)置重試次數(shù))【新增】 --> <dubbo:reference interface="com.atguigu.gmall.service.UserService" id="userService" timeout="5000" retries="3" version="*"> <!-- <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method> --> </dubbo:reference> <!-- 配置當(dāng)前消費(fèi)者的統(tǒng)一規(guī)則:所有的服務(wù)都不檢查 --> <dubbo:consumer check="false" timeout="5000"></dubbo:consumer> <dubbo:monitor protocol="registry"></dubbo:monitor> <!-- <dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor> --> </beans>
消費(fèi)者建一個(gè)實(shí)現(xiàn)類(lèi),直接使用提供者的方法,如下:
@Service public class OrderServiceImpl implements OrderService { @Autowired UserService userService; @Override public List<UserAddress> initOrder(String userId) { // TODO Auto-generated method stub System.out.println("用戶id:"+userId); //1、查詢用戶的收貨地址 List<UserAddress> addressList = userService.getUserAddressList(userId); for (UserAddress userAddress : addressList) { System.out.println(userAddress.getUserAddress()); } return addressList; } }
啟動(dòng)消費(fèi)者 main 方法,如下:
public class MainApplication { @SuppressWarnings("resource") public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml"); OrderService orderService = applicationContext.getBean(OrderService.class); orderService.initOrder("1"); System.out.println("調(diào)用完成...."); System.in.read(); } }
可以看到輸出:

由此,消費(fèi)者調(diào)用提供者提供的服務(wù)即完成。
(上面的示例沒(méi)有把 dubbo-interface 工程具體寫(xiě)出來(lái),可以參考下面 3.2)
3.2、springboot搭建dubbo示例
創(chuàng)建工程 dubbotest01,在該工程下創(chuàng)建 module:dubbo-interface、dubbo-provider、dubbo-consumer。其中,dubbo-provider 和 dubbo-consumer 創(chuàng)建為 springboot 項(xiàng)目,可用于測(cè)試服務(wù)調(diào)用,dubbo-interface 只需創(chuàng)建為普通 maven 項(xiàng)目即可,只需在里面管理一些公共接口類(lèi)。dubbo-interface 后面被打成 jar 包,它的作用只是提供接口。

3.2.1、搭建dubbo-interface 模塊
在 dubbo-interface 模塊中創(chuàng)建接口類(lèi) HelloService,如下:
package com.example.dubbointerface; public interface HelloService { public String sayHello(String name); }
3.2.2、搭建dubbo-provider模塊
dubbo-provider 中添加依賴,包括dubbo 、zookeeper以及 dubbo-interface 的依賴,如下:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--引入dubbo-interface的依賴--> <dependency> <groupId>com.example</groupId> <artifactId>dubbo-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!--引入dubbo的依賴--> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- 引入zookeeper的依賴 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> </dependencies>
在 application.properties 配置文件中配置 dubbo 相關(guān)信息
# 配置應(yīng)用啟動(dòng)端口,避免端口沖突 server.port=8333 spring.dubbo.application.name=dubbo-provider spring.dubbo.application.registry=zookeeper://192.168.118.131:2181 #可通過(guò)以下配置修改默認(rèn)的20880端口 spring.dubbo.protocol.port=20883
實(shí)現(xiàn) HelloService 接口,如下:
import com.alibaba.dubbo.config.annotation.Service; import org.springframework.stereotype.Component; @Component @Service //將這個(gè)類(lèi)提供的方法(服務(wù))對(duì)外發(fā)布,將訪問(wèn)的地址、ip、路徑注冊(cè)到注冊(cè)中心。(注意,@Service 注解使用的時(shí) Dubbo 提供的而不是 Spring 提供的。) public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { return "Hello " + name; } }
給啟動(dòng)類(lèi)加上 @EnableDubboConfiguration 注解開(kāi)啟Dubbo 的自動(dòng)配置。
import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication // 開(kāi)啟dubbo的自動(dòng)配置 @EnableDubboConfiguration public class DubboProviderApplication { public static void main(String[] args) { SpringApplication.run(DubboProviderApplication.class, args); } }
3.2.3、搭建dubbo-consumer模塊
dubbo-consumer 中添加依賴,包括dubbo 、zookeeper以及 dubbo-interface 的依賴,如下:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>dubbo-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!--引入dubbo的依賴--> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- 引入zookeeper的依賴 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> </dependencies>
在 application.properties 配置文件中配置 dubbo 相關(guān)信息
# 配置端口 server.port=8330 spring.dubbo.application.name=dubbo-consumer spring.dubbo.application.registry=zookeeper://192.168.118.131:2181 #可通過(guò)以下配置修改默認(rèn)的20880端口 spring.dubbo.protocol.port=20884
編寫(xiě)一個(gè)簡(jiǎn)單 Controller ,HelloController 來(lái)調(diào)用遠(yuǎn)程服務(wù),如下:
import com.alibaba.dubbo.config.annotation.Reference; import com.example.dubbointerface.HelloService; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { /** 1.從zookeeper注冊(cè)中心獲取對(duì)應(yīng)服務(wù)提供者的訪問(wèn)路徑 2.進(jìn)行遠(yuǎn)程調(diào)用RPC 3.將結(jié)果封裝為一個(gè)代理對(duì)象,給變量賦值 */ @Reference //遠(yuǎn)程注入 private HelloService helloService; @RequestMapping("/hello") public String hello() { String hello = helloService.sayHello("world"); System.out.println(helloService.sayHello("SnailClimb")); return hello; } }
給啟動(dòng)類(lèi)加上 @EnableDubboConfiguration 注解開(kāi)啟Dubbo 的自動(dòng)配置。
import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource; @SpringBootApplication @EnableDubboConfiguration public class DubboConsumerApplication { public static void main(String[] args) { SpringApplication.run(DubboConsumerApplication.class, args); } }
啟動(dòng) zookeeper,啟動(dòng) provider 和 consumer 服務(wù),調(diào)用 consumer 服務(wù)的 HelloController 類(lèi),即訪問(wèn) http://localhost:8330/hello,可以看到輸出如下:

由此,使用SpringBoot+Dubbo 搭建分布式服務(wù)成功。
4、zookeeper管理控制臺(tái)(dubbo-admin)
dubbo-admin 管理平臺(tái),是圖形化的服務(wù)管理頁(yè)面。該平臺(tái)從注冊(cè)中心中獲取到所有的提供者 / 消費(fèi)者,可進(jìn)行配置管理 路由規(guī)則、動(dòng)態(tài)配置、服務(wù)降級(jí)、訪問(wèn)控制、權(quán)重調(diào)整、負(fù)載均衡等管理功能。
4.1、dubbo-admin的安裝使用
4.1.1、dubbo-admin下載打包
dubbo-admin 是一個(gè)前后端分離的項(xiàng)目,前端使用vue,后端使用springboot。
dubbo-admin下載地址 :https://github.com/apache/dubbo-admin
下載解壓后進(jìn)入 dubbo-admin-server\src\main\resources 目錄,找到 application.properties 配置文件進(jìn)行配置修改,將 zookeeper 地址修改為正確地址,如:
# centers in dubbo2.7, if you want to add parameters, please add them to the url admin.registry.address=zookeeper://192.168.118.131:2181 admin.config-center=zookeeper://192.168.118.131:2181 admin.metadata-report.address=zookeeper://192.168.118.131:2181
在 dubbo-admin-develop 根目錄執(zhí)行打包命令:mvn clean package -Dmaven.test.skip=true,看到 build success 即打包成功。

(
- 或者先在 dubbo-admin-server 中打包,使用 mvn package -Dmaven.test.skip=true ,
- 然后 java -jar 啟動(dòng)打包生成的 jar 包,如:java -jar dubbo-admin-server-0.3.0.jar。
- 然后再去 dubbo-admin-ui 里面執(zhí)行 npm install 等待下載前端的依賴,完畢后啟動(dòng)前端 npm run dev
)
如果 dubbo-admin-server 編譯報(bào)錯(cuò),提示 zookeeper server創(chuàng)建失敗什么的,可將上面的 admin.registry.address 配置改為:
admin.registry.address=zookeeper://192.168.118.131:2181?blockUntilConnectedWait=100000&timeout=100000
4.1.2、啟動(dòng)前后端
切換到目錄打包后的后端 jar 包目錄:dubbo-Admin-develop\dubbo-admin-distribution\target,執(zhí)行以下命令啟動(dòng)后臺(tái):
java -jar .\dubbo-admin-0.1.jar
在 dubbo-admin-ui 目錄下執(zhí)行以下命令啟動(dòng)前端:
npm run dev
啟動(dòng)完成后即可通過(guò) localhost:8081 看到后臺(tái)管理頁(yè)面了,啟動(dòng)結(jié)果如下:(默認(rèn)登錄賬戶密碼都是 root)

4.2、dubbo-admin的基本使用
可以在服務(wù)查詢中看到已注冊(cè)的服務(wù),如下:

點(diǎn)擊服務(wù)的詳情,可以看到該服務(wù)的詳細(xì)信息和該服務(wù)的消費(fèi)者,如下:



浙公網(wǎng)安備 33010602011771號(hào)