(項目以springboot進行開啟與構建,注冊中心采用zookeeper)
一、認識Dubbo
- Dubbo是一款高性能Java RPC框架,具體是什么來路,為什么要使用他可參考他的官方文檔,里面包含了所有從介紹到上手使用的細節,本文著重于描述和總結使用springboot+dubbo+zookeeper開發一個實戰案例,作為新手的快速起步。
- Dubbo出自阿里巴巴之手,現在開源給了Apache。
- 與其類似框架:springcloud
二、開始上手
2.1必須理解的概念:
2.1.1官方文檔內容:
0、服務容器負責啟動,加載,運行服務提供者。
1、服務提供者在啟動時,向注冊中心注冊自己提供的服務。
2、服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
3、注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送
4、變更數據給消費者。
5、服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
6、服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
2.2.2流程概括
- 服務提供者provider(相當于以前的service層的實現)單獨部署并運行在容器container內(tomcat之類);服務消費者consumer(相當于以前的controller)也單獨部署運行,其中會調用service曾的一些服務進行消費,由于兩者已進行分離并單獨部署需要通過網絡來進行調用和通信,我們稱這樣的調用為遠程調用(RPC);
2.2.3疑問解答
-
既然需要相互通信,provider和consumer直接是如何相互知道對方的?
- 兩者啟動后向注冊中心注冊,兩者通過注冊中心registry注冊和發現
-
我可以從哪里來檢測所有的服務運行情況?
- 通過監控中心monitor來查看和管理。Dubbo2.6.0及之前,自帶一個admin來幫助我們查看和管理所有注冊在注冊中心上的服務應用,在2.6.0以后統一整合為一套新的控制臺“dubbo-ops”
-
由于controller和service實際開發已經分離,如何調用解決依賴問題?
- 通過單獨構建一個接口項目service打包并在兩者中進行依賴引入
-
dubbo支持多種注冊中心,為什么一般都采用zookeeper?zk究竟起到什么作用?
- zookeeper作為一款本身支持分布式的、對分布式服務和應用進行協調管理的產品,完美解決了人為在分布式環境中協調和管理服務過程的復雜,本身的分布式還有利于服務的穩定(集群中一半以下節點宕機照樣正常使用)。【但是本段解釋也有問題,因為dubbo產生的原因是由于以前開發分布式系統采用各種注冊中心配置的復雜,dubbo產生就是為了統一這些復雜性,通過簡單配置即可完成分布式系統的比如服務注冊等操作】
2.2開始demo開發
2.2.1確定目標
- 從前面的理解中,我們應該得到,相比以前做的后端項目(三層架構——控制層、服務層、持久化層)結構需要改變為/也是dubbo推薦的改為如下模式:建立三個項目provider、consumer、service,即:
1、服務消費者consumer項目——相當于以前的controller層做的事情
2、服務提供者provider項目——相當于以前的service層的實現類+dao/mapper持久層做的事情
3、service接口項目——相當于以前service層的接口,用于provider、consumer正常開發的依賴
2.2.2開始開發service接口項目
-
使用idea集成開發環境新建一個不帶模板的maven項目(service項目僅用于打包并做另外兩個項目的依賴,不用進一步部署,所以直接建立maven項目即可)
image.png
image.png
image.png -
新建接口UserService,在com.toketec.dubboServiceDemo.service包下:
image.png
image.png -
編寫接口內容,這里定義一個返回User類型的接口方法getUser()
image.png -
類型缺失?新建User類,在com.toketec.dubboServiceDemo.model包下面【以后一般需要用于項目之間進行傳遞的實體類(通常都是持久層與數據庫打交道的類)也會存放在service接口項目中,provider、consumer項目進行依賴引入就可以一起引用該類型了】
image.png
image.png -
注意,dubbo采用二進制進行傳輸,實體類必須實現序列化接口
image.png -
實體類內定義一些字段和各種get\set\toString...
image.png -
在剛剛的UserService接口中import User類
image.png 至此,service接口項目就完成了,下面打包安裝即可在其他maven項目中直接引入,(你也可以找到maven本地倉庫,找到對應的jar/war包單獨復制到其他非maven構建的項目中作為依賴)。
-
打包安裝:
image.png 安裝成功:
2.2.3開發provider提供者項目
·使用idea集成開發環境新建一個springboot項目,帶web起步依賴。(注意要等待項目自動構建加載完成,需要聯網,如果卡主很久建議退出重新打開idea,重新打開新建的項目,maven可以換成阿里云鏡像更快)
-
新建在com.toketec.dubboProviderDemo包下新建包service.impl,并新建實現類UserServiceImpl
image.png -
實現UserService接口
image.png -
缺少依賴?導入我們的接口項目所打包的依賴即可,在provider項目的pom文件的依賴中加入剛剛在service接口項目pom文件中的<groupId>等如下內容:
<dependency> <groupId>com.toketec</groupId> <artifactId>dubbo-serviceDemo</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
-
這里由于我們使用到了dubbo和zoookeeper的內容,我們順便把他們的依賴也一起加入項目中,dubbo有針對Springboot的起步依賴,所以,我們添加如下內容:【注意,如果我們采用的Springboot是1.x.x版本,那么dubbo要采用1.0.0,若2.x.x那么采用2.0.0】
<dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
-
添加完依賴,實現接口中的getUser方法,如果有數據庫也可以整合并使用數據庫內容。為了演示方便,這里我們直接返回一個指定的User對象id=10,age=100,name=小王,未來調用本服務的消費者就會得到這樣一個User對象的數據。
image.png -
在以前的ssm項目中,我們會在service的實現類上直接加上@Service注解表示是一個spring的bean,但是由于現在我們要采用的dubbo也有一個@Service注解來進行服務注冊,沖突怎么辦?好在Spring中@Service、@Controller、@Component等一些注解都本質沒有任何區別,只是表面意思不同增加可讀性,所以我們可以在本實現類上添加如下注解:
image.png -
接下來進行配置,打開application.properties/yml即Springboot的核心配置文件,添加如下內容:
#本項目容器啟動后的端口(tomcat端口) server.port=8080 #本應用的名字命名 spring.dubbo.application.name=dubbo-provider-demo #配置注冊中心 #注冊中心是真集群,存在多個節點,這樣配置(ip和端口改成你自己配置的zookeeper地址和端口你也可以采用其他注冊中心) spring.dubbo.application.registries[0].address=zookeeper://10.101.80.101:2181 spring.dubbo.application.registries[0].registry="reg1" spring.dubbo.application.registries[1].address=zookeeper://10.101.80.102:2181 spring.dubbo.application.registries[1].registry="reg2" spring.dubbo.application.registries[2].address=zookeeper://10.101.80.103:2181 spring.dubbo.application.registries[2].registry="reg3" #注冊中心只有一個節點做測試的時候 #spring.dubbo.registry=zookeeper://10.101.80.101:2181 #配置service服務掃描所在包,告訴dubbo服務在哪里 spring.dubbo.scan=com.toketec.dubboProviderDemo.service
-
最后,在Springboot的main 方法所在類加上dubbo自動配置注解:
image.png -
運行main方法,啟動provider項目:
image.png 可以看到三個節點都連上了注冊成功,tomcat也成功啟動。
-
dubbo2.6提供的admin中可以看到我們注冊的服務
image.png
2.2.4開發consumer消費者項目
·使用idea集成開發環境新建一個springboot項目,帶web起步依賴。(注意要等待項目自動構建加載完成,需要聯網,如果卡主很久建議退出重新打開idea,重新打開新建的項目,maven可以換成阿里云鏡像更快)
-
在com.toketec.dubboConsumerDemo包中新建包controller,并新建一個UserController類
image.png -
在UserController中寫一個getMyUser()方法,要求對外暴露的url為“/getMyUser.do”、需要調用UserService的getUser()方法、同時采用json字符串進行返回(像以前ssm項目一樣寫,不再贅述)
image.png -
缺少依賴?與上文中描述相同,引入我們的service接口項目的依賴即可,因為用的dubbo和zookeeper,這里順便全部引入,上文已有描述,這里不再贅述
<dependency> <groupId>com.toketec</groupId> <artifactId>dubbo-serviceDemo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
-
如果是以前的ssm單獨項目,接下來你可能會使用依賴注入方式注入UserService,但是,現在服務已經分離并單獨部署,我們需要通過dubbo提供的方式來進行遠程調用。
-
只需將以前的@Autowired注解改成dubbo提供的@Reference(version = "1.0")即可,版本號根據實際需要改變和增減。
image.png
-
-
接下來進行配置,打開application.properties/yml即Springboot的核心配置文件,配置的內容和上文配置provider完全一致【注意!server.port代表tomcat的端口,需要改成本機不被占用的端口我這里假設改成9090,否則無法使用,還有應用名也改成不同的,以作區分】,最終如下:
#本項目容器啟動后的端口(tomcat端口) server.port=9090 #本應用的名字命名 spring.dubbo.application.name=dubbo-consumer-demo #配置注冊中心 #注冊中心是真集群,存在多個節點,這樣配置(ip和端口改成你自己配置的zookeeper地址和端口你也可以采用其他注冊中心) spring.dubbo.application.registries[0].address=zookeeper://10.101.80.101:2181 spring.dubbo.application.registries[0].registry="reg1" spring.dubbo.application.registries[1].address=zookeeper://10.101.80.102:2181 spring.dubbo.application.registries[1].registry="reg2" spring.dubbo.application.registries[2].address=zookeeper://10.101.80.103:2181 spring.dubbo.application.registries[2].registry="reg3" #注冊中心只有一個節點做測試的時候 #spring.dubbo.registry=zookeeper://10.101.80.101:2181
-
最后,同樣在Springboot的main 方法所在類加上dubbo自動配置注解:
image.png -
運行main方法,啟動consumer項目:
image.png
2.3開發完成,demo測試
2.3.1瀏覽器訪問localhost:9090/getMyUser.do
(這里的端口就是consumer項目中定義的端口)
成功得到了正確的返回,證明我們的本個案例開發成功!
2.3.2可能踩得坑(來自https://blog.csdn.net/sly5400415/article/details/84953479)
1、實體類沒有實現序列化
2、在提供者端使用的service注解是alibaba包的,不是springboot默認的
3、springbootparent最新會有兼容性問題,直接用demo的pom上的版本,成功了再去測試兼容性吧
4、pom中zookeeper的和自己下載的版本不一致
5、zookeeper集群沒有搭建完好
6、使用過虛擬機的單位注意了,需要禁用虛擬網卡
7、注解上的version等設置是否一致