本文目錄一覽:
JAVA分布開發dubbo問題
首先要搞清楚三者的概念
1、Dubbo是阿里開源的默認基於TCP協議RPC遠程服務調度框架,簡單理解就是服務A使用TCP協議調用服務B的Dubbo介面。
2、Zookeeper是註冊中心,在這裡主要用於管理dubbo服務提供者和消費者的註冊信息與服務調度時提供相關依據。
3、Tomcat是WEB應用伺服器,可以對外暴露基於HTTP協議的服務介面。
由於用戶訪問你的應用首先是通過瀏覽器,也就是基於HTTP協議,所以必須對外暴露HTTP介面作為入口,那麼就需要使用WEB應用伺服器,比如Tomcat、Jetty、Undertow等等。
關於不啟動tomcat,需要哪些配置的問題如下:
Dubbo支持HTTP協議,但原理任然是通過WEB應用伺服器暴漏一個埠。從Dubbo本身專註的領域來說,不建議用HTTP協議,所以最終的結論是,服務與服務之間的介面調用使用Dubbo,而對外暴露HTTP介面任然使用WEB應用伺服器。
從零開始認識Dubbo
[TOC]
1.Dubbo是什麼
Apache Dubbo 是一款高性能Java RPC框架。
Dubbo是一個分散式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,如果沒有分散式的需求,其實是不需要用的,只有在分散式的時候,才有dubbo這樣的分散式服務框架的需求,並且本質上是個服務調用的東東, 說白了就是個遠程服務調用的分散式框架(告別Web Service模式中的WSdl,以服務者與消費者的方式在dubbo上註冊) 其核心部分包含:
2.Dubbo能做什麼
Dubbo採用全spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring載入Dubbo的配置即可,Dubbo基於Spring的Schema擴展進行載入。
3.Dubbo架構
節點角色說明:
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與發現的註冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
調用關係說明:
4.Dubbo的使用方法
Dubbo採用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring載入Dubbo的配置即可,Dubbo基於Spring的Schema擴展進行載入。如果不想使用Spring配置,可以通過API的方式進行調用(註解式,不推薦使用)
下載安裝zookeeper註冊中心(不建議使用multicast)
1.Windows
下載地址:
使用方法:下載解壓即可,進入解壓目錄運行zkServer.cmd啟動註冊服務中心
截圖:
2.MacOS
下載地址:
使用方法:下載解壓即可,進入解壓目錄運行zkServer.sh start啟動註冊服務中心
3.Linux
下載地址:
使用方法:下載解壓即可,進入解壓目錄運行zkServer.sh start啟動註冊服務中心
服務提供者
1.定義服務介面(該介面需單獨打包,在服務提供方和消費方共享)
DemoService.java
2.服務提供方實現介面:(對服務消費方隱藏實現)
DemoServiceImpl.java
dubbo-provider.xml:
4.載入Spring配置,啟動服務:
Provider.java:
或者使用springBoot啟動
服務消費者:
applicationContext-dubbo.xml 中註冊自己需要調用的介面。
1.通過Spring配置引用遠程服務
dubbo-consumer.xml:
2.載入Spring配置,並調用遠程服務:
Consumer.java
或者使用springBoot啟動
並添加對應的restful介面提供介面訪問
修改對應index頁面
3.dubbo管理頁面:
啟動後訪問
輸入賬號密碼root/root
應用頁面:
提供者頁面:
消費者頁面:
服務頁面:
測試是否成功,只要看狀態是否正常,就ok了 ….
provider-log:
5.使用Dubbo可能遇到的問題
1、org.springframework.beans.factory.BeanCreationException
原因分析:
解決方案
2、org.apache.dubbo.rpc.RpcException
原因分析
解決方案
可能是因為providers沒有啟動,或者是provider對應暴露的服務被禁用,啟動providers或者解除禁用即可
3、java.lang.IllegalStateException
原因分析
解決方案
總結以上兩點,通俗點講,就是重啟了工程(可能是因為直接修改代碼,工程reload了), 並且,連過了資料庫(登錄等),才出現了上述報錯信息。原因是因為在tomcat重啟的時候,之前的tomcat的線程還沒有完全關閉,最新啟動tomcat就會報這個異常。
4、org.apache.dubbo.remoting.TimeoutException
原因分析
解決方案
在dubbo-provider.xml增加超時時間
Dubbo 協議
Dubbo是 Alibaba 開源的分散式服務框架遠程調用框架,在網路間傳輸數據,就需要通信協議和序列化。
Dubbo支持dubbo、rmi、hessian、http、webservice、thrift、redis等多種協議,但是Dubbo官網是推薦我們使用Dubbo協議的,默認也是用的dubbo協議。
先介紹幾種常見的協議:
預設協議,使用基於mina1.1.7+hessian3.2.1的tbremoting交互。
連接個數:單連接
連接方式:長連接
傳輸協議:TCP
傳輸方式:NIO非同步傳輸
序列化:Hessian二進位序列化
適用範圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓滿提供者,盡量不要用dubbo協議傳輸大文件或超大字元串。
適用場景:常規遠程服務方法調用
1、dubbo默認採用dubbo協議,dubbo協議採用單一長連接和NIO非同步通訊,適合於小數據量大並發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況
2、他不適合傳送大數據量的服務,比如傳文件,傳視頻等,除非請求量很低。
配置如下:
dubbo:protocol name=”dubbo” port=”20880″ /
dubbo:protocol name=「dubbo」 port=「9090」 server=「netty」 client=「netty」 codec=「dubbo」
serialization=「hessian2」 charset=「UTF-8」 threadpool=「fixed」 threads=「100」 queues=「0」 iothreads=「9」
buffer=「8192」 accepts=「1000」 payload=「8388608」 /
3、Dubbo協議預設每服務每提供者每消費者使用單一長連接,如果數據量較大,可以使用多個連接。
dubbo:protocol name=”dubbo” connections=”2″ /
4、為防止被大量連接撐掛,可在服務提供方限制大接收連接數,以實現服務提供方自我保護
dubbo:protocol name=”dubbo” accepts=”1000″ /
Java標準的遠程調用協議。
連接個數:多連接
連接方式:短連接
傳輸協議:TCP
傳輸方式:同步傳輸
序列化:Java標準二進位序列化
適用範圍:傳入傳出參數數據包大小混合,消費者與提供者個數差不多,可傳文件。
適用場景:常規遠程服務方法調用,與原生RMI服務互操作
RMI協議採用JDK標準的java.rmi.*實現,採用阻塞式短連接和JDK標準序列化方式 。
基於Hessian的遠程調用協議。
連接個數:多連接
連接方式:短連接
傳輸協議:HTTP
傳輸方式:同步傳輸
序列化:表單序列化
適用範圍:傳入傳出參數數據包大小混合,提供者比消費者個數多,可用瀏覽器查看,可用表單或URL傳入參數,暫不支持傳文件。
適用場景:需同時給應用程序和瀏覽器JS使用的服務。
1、Hessian協議用於集成Hessian的服務,Hessian底層採用Http通訊,採用Servlet暴露服務,Dubbo預設內嵌Jetty作為伺服器實現。
2、Hessian是Caucho開源的一個RPC框架: ,其通訊效率高於WebService和Java自帶的序列化。
基於http表單的遠程調用協議。參見:[HTTP協議使用說明]
連接個數:多連接
連接方式:短連接
傳輸協議:HTTP
傳輸方式:同步傳輸
序列化:表單序列化
適用範圍:傳入傳出參數數據包大小混合,提供者比消費者個數多,可用瀏覽器查看,可用表單或URL傳入參數,暫不支持傳文件。
適用場景:需同時給應用程序和瀏覽器JS使用的服務。
基於WebService的遠程調用協議。
連接個數:多連接
連接方式:短連接
傳輸協議:HTTP
傳輸方式:同步傳輸
序列化:SOAP文本序列化
適用場景:系統集成,跨語言調用
序列化是將一個對象變成一個二進位流就是序列化, 反序列化是將二進位流轉換成對象
為什麼要序列化?
Dubbo序列化支持java、compactedjava、nativejava、fastjson、dubbo、fst、hessian2、kryo,其中默認hessian2。其中java、compactedjava、nativejava屬於原生java的序列化。
hessian2序列化:hessian是一種跨語言的高效二進位序列化方式。但這裡實際不是原生的hessian2序列化,而是阿里修改過的,它是dubbo RPC默認啟用的序列化方式。
json序列化:目前有兩種實現,一種是採用的阿里的fastjson庫,另一種是採用dubbo中自己實現的簡單json庫,但其實現都不是特別成熟,而且json這種文本序列化性能一般不如上面兩種二進位序列化。
java序列化:主要是採用JDK自帶的Java序列化實現,性能很不理想。
Dubbo簡介
Dubbo是Alibaba開源的分散式服務框架,它按照分層的方式來架構,使用這種方式可以使各層解耦。
Dubbo在調用遠程的服務的時候再本地有一個介面,就想調用本地方法一樣去調用,底層實現好參數傳輸和遠程服務運行結果傳回之後的返回。
Dubbo的特點:
(1)它主要使用高效的網路框架和序列化框架,讓分散式服務之間調用效率更高。
(2)採用註冊中心管理眾多的服務介面地址,當你想調用服務的時候只需要跟註冊中心詢問即可,不像使用WebService一樣每個服務都得記錄好介面調用方式。
(3)監控中心時實現服務方和調用方之間運行狀態的監控,還能控制服務的優先順序、許可權、權重、上下線等,讓整個龐大的分散式服務系統的維護和治理比較方便。
(4)高可用,如果有服務掛了,註冊中心就會從服務列表去掉該節點,客戶端會像註冊中心請求另一台可用的服務節點重新調用。同時註冊中心也能實現高可用(ZooKeeper)。
(5)負載均衡,採用軟負載均衡演算法實現對多個相同服務的節點的請求負載均衡。
Dubbo需要四大基本組件:Rigistry,Monitor,Provider,Consumer。
1、監控中心的配置文件-dubbo.properties文件
(1)容器,監控中心是在jetty和spring環境下運行,依賴於註冊中心,日誌系統是log4j
dubbo.container = log4j,spring,registry,jetty
(2)監控服務的名稱,監控系統對整個Dubbo服務系統來說也是一個服務
dubbo.application.name = simple-monitor
(3)服務的所有者,這是Dubbbo的服務的功能,可以指定服務的負責人
dubbo.application.owner = coselding
(4)註冊中心的地址,配置後監控中心就能通過註冊中心獲取當前可用的服務列表及其狀態,在頁面向你彙報Dubbo中的服務運行情況。
dubbo.registr.address = multicast://{ip}:{port} //廣播
dubbo.registr.address = zookeeper://{ip}:{port} //zookeper
dubbo.registr.address = redis://{ip}:{port} //redis
dubbo.registr.address = dubbo://{ip}:{port} //dubbo
(5)dubbo協議埠號
dubbo.protocol.port = 7070
(6)jetty工作埠號
dubbo.jetty.port = 8082
(7)工作目錄,用於存放監控中心的數據
dubbo.jetty.directory = ${user.home}/monitor
(8)監控中心報表存放目錄
dubbo.charts.directory=${dubbo.jetty.directory}/charts
(9)監控中心數據資料目錄
dubbo.statistics.directory=${user.home}/monitor/statistics
(10)監控中心日誌文件路徑
dubbo.log4j.file=logs/dubbo-monitor-simple.log
(11)監控中心日誌記錄級別
dubbo.log4j.level=WARN
2、Dubbo提供負載均衡方式
(1)Random,隨機,按權重配置隨機概率,調用量越大分布越均勻,默認方式。
(2)RounRobin,輪詢,按權重設置輪詢比例,如果存在比較慢的機器容易在這台機器上請求阻塞較多。
(3)LeastActive,最少活躍調用數,不支持權重,只能根據自動識別的活躍數分配,不能靈活調配。
(4)ConsistenHash,一致性hash,對相同參數的請求路由到一個服務提供者上,如果有類似灰度發布需求可採用。
3、Dubbo過濾器
Dubbo初始化過程載入ClassPath下的META-INF/dubbo/internal/,META-INF/dubbo/,META-INF/services/三個路徑下的com.alibaba.dubbo.rpc.Filter文件。文件內容:
Name = FullClassName,這些類必須實現Filter介面。
自定義Filter類:
配置文件在配置過濾器,consumer.xml中:
Dubbo對過濾器的載入過程:
先載入三個路徑下的com.alibaba.dubbo.rpc.Filter文件裡面的鍵值對,key為過濾器名稱,value為過濾器的類的全限定名(這個類必須實現Dubbo中的Filter介面)。
自定義的類中@Active註解是過濾器設定的全局基本屬性。
Spring在載入consumer.xml文件時,通過 dubbo:consumer filter=”xxx” id = “xxx” retrries = “0”這個配置指定消費者端要載入的過濾器,通過filter屬性指定過濾器名稱。
@Activate註解-自動激活,group屬性是表示匹配了對應的角色才被載入,value表示表明過濾條件,不寫則表示所有條件都會被載入,寫了則只有dubbo URL中包含該參數名且參數值不為空才被載入,這個參數會以dubbo協議的一個參數K-V對傳到Provider。
4、Dubbo的Provider配置
5、Dubbo的Consumer配置
1、Dubbo是什麼?
Dubbo是阿里巴巴開源的基於Java的高性能RPC分散式框架。
2、為什麼使用Dubbo?
很多公司都在使用,經過很多線上的考驗,內部使用了Netty,Zookeeper,保證了高性能可用性。
使用Dubbo可以將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,可以提高業務復用靈活性擴展,使前端應用能快速的響應對邊的市場需求。分散式架構可以承受更大規模的並發流量。
Dubbo的服務治理圖:
3、Dubbo和Spring Cloud的區別
兩個沒有關聯,但是非要說區別,有如下幾點:
(1)通信方式不同,Dubbo使用RPC通信,Spring Cloud使用HTTP Restful方式
(2)組成部分不同
4、Dubbo支持的協議
dubbo:// (推薦);rmi:// ;hessian:// ;http:// ;webservice:// ;thrift:// ;memcached:// ;redis:// ;rest:// 。
5、Dubbo需要容器嗎?
不需要,如果硬要容器的話,會增加複雜性,同時也浪費資源。
6、Dubbo內置的服務容器
Spring Container;Jetty Container;Log4j Container。
7、Dubbo中節點角色
Register,Monitor,Provider,Consumer,Container(服務運行的容器)。
8、Dubbo的服務註冊和發現的流程圖
9、Dubbo的註冊中心
默認使用Zookeper作為註冊中心,還有Redis,Multicast,dubbo註冊中心。
10、Dubbo的配置方式
Spring配置方式和Java API配置方式
11、Dubbo的核心配置
(1)dubbo:service 服務配置
(2)dubbo:referece 引用配置
(3)dubbo:protocol 協議配置
(4)dubbo:application 應用配置
(5)dubbo:registry 註冊中心配置
(6)dubbo:monitor 監控中心配置
(7)dubbo:provider 提供方配置
(8)dubbo:consumer 消費方配置
(9)dubbo:method 方法配置
(10)dubbo:argument 參數配置
12、在Provider 節點上可以配置Consumer端的屬性有哪些?
(1)timeout:方法調用超時
(2)retries:失敗重試次數,默認是2次
(3)loadbalance:負載均衡演算法,默認隨機
(4)actives消費者端,最大並發調用控制
13、Dubbo啟動時如果依賴的服務不可用會怎樣
Dubbo預設會在啟動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止Spring初始化完成。默認check =”true”。
14、Dubbo序列化框架
推薦使用Hessian序列化,還有Dubbo,FastJson,Java自帶序列化。
15、Dubbo的通信框架
默認使用Netty框架,另外也提供了Mina,Grizzly。
16、Dubbo集群容錯方案
(1)Failover Cluster,失敗自動切換,自動重試其他伺服器。
(2)Failfast Cluster,快速失敗,立即報錯,只發起一次調用。
(3)Failsafe Cluster,失敗安全,出現異常時,直接忽略。
(4)Failback Cluster,失敗自動恢復,記錄失敗請求,定時重發。
(5)Forking Cluster,並行調用多個伺服器,只要一個返回成功即可。
(6)Broadcast Cluster,廣播逐個調用所有提供者,任意一個報錯則報錯。
17、Dubbo的負載均衡策略
(1)Random LoadBalance,隨機,按權重設置隨機概率,默認。
(2)RoundRobin LoadBalace,輪詢,按公約後的權重設置輪訓比例。
(3)LeastActive LoadBalace,最少活躍調用數,相同活躍數的隨機。
(4)ConsistenHash LoadBalance,一致性hash,相同參數的請求總是發到用一個伺服器。
18、指定某一個服務
可以配置環境點對點直連,繞過註冊中心,將以服務介面為單位,忽略註冊中心的提供者列表。
dubbo:reference interface=”com.weidian.dubbo.IMyDemo” version=”1.0″ id=”myDemo” url=”dubbo://127.0.0.1:20880/”/dubbo:reference
19、Dubbo多協議
Dubbo允許配置多協議,在不同伺服器上支持不同協議,或者同一服務支持多種協議。
20、當一個服務有多種實現時怎麼做?
當一個介面有多種是現實,可以用group屬性來分組,服務提供方和消費方都指定同一個group即可。
21、兼容舊版本
使用版本號過度,多個不同版本的服務註冊到註冊中心,版本號不同的服務相互間不引用。
22、Dubbo可以緩存嗎?
Dubbo提供聲明式緩存,用於加速熱門數據的訪問速度,以減少用戶加緩存的工作量。
23、Dubbo服務之間的調用時阻塞的嗎?
默認是同步等待結果阻塞的,支持非同步調用。Dubbo是基於NIO的非阻塞實現並行調用的,客戶端不需要啟動多線程即可完成並行調用多個遠程服務,相對多線程開銷較小,非同步調用會返回一個Future對象。
24、Dubbo不支持分散式事務
25、Dubbo必須依賴的包
Dubbo必須依賴JDK,其他為可選。
26、Dubbo使用過程中的問題
Dubbo的設計目的是為了滿足高並發小數據量的rpc請求,在大數據量下性能表現不是很好,建議使用rmi或http協議。
27、Dubbo的管理控制台的作用
路由規則,動態配置,服務降級,訪問控制,權重調整,負載均衡。
28、Spring boot整合Dubbo
(1)添加依賴
!– —
dependency
groupIdcom.alibaba.boot/groupId
artifactIddubbo-spring-boot-starter/artifactId
version0.1.0/version
/dependency
!– —
dependency
groupIdcom.101tec/groupId
artifactIdzkclient/artifactId
version0.10/version
/dependency
(2)配置dubbo
## Dubbo 服務提供者配置
spring.dubbo.application.name=provider
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=20880
spring.dubbo.scan=org.spring.springboot.dubbo
## Dubbo 服務消費者配置
spring.dubbo.application.name=consumer
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.scan=org.spring.springboot.dubbo
說一下Dubbo的工作原理?註冊中心掛了可以繼續通信嗎?
答案是肯定可以的,我將從下面幾點進行說明:
1.dubbo 的調用流程
2.Dubbo整體設計
3.從源碼上說明註冊中心掛了還是可以繼續通信的
Dubbo 調用流程
架構圖
流程說明:
1.Provider(提供者)綁定指定埠並啟動服務
2.提供者連接註冊中心,並發本機IP、埠、應用信息和提供服務信息發送至註冊中心存儲
3.Consumer(消費者),連接註冊中心 ,並發送應用信息、所求服務信息至註冊中心
4.註冊中心根據 消費 者所求服務信息匹配對應的提供者列表發送至Consumer 應用緩存。
5.Consumer 在發起遠程調用時基於緩存的消費者列表擇其一發起調用。
6.Provider 狀態變更會實時通知註冊中心、在由註冊中心實時推送至Consumer
這麼設計的意義:
Dubbo 整體設計
其協作流程如下:
從源碼上說明註冊中心掛了還是可以繼續通信的
首先要把消費者註冊到Zookeeper註冊中心
然後使用RegistryDirectory 監聽一下幾個目錄(會自動觸發一次去獲取這些目錄上的當前數據)
當前所引入的服務的動態配置目錄:/dubbo/config/dubbo/org.apache.dubbo.demo.DemoService:1.1.1:g1.configurators
比如監控providers 目錄:
當有服務提供者註冊,zookeeper會自動推動給訂閱的消費者,然後轉換為invoker存儲到緩存中
我們在看調用時的代碼:
我們看到 FailoverClusterInvoker 的doInvoke方法
Invoker invoker = select(loadbalance, invocation, copyInvokers, invoked);
此方法根據負載均衡器去緩存中獲取一個invoker,
上面的 copyInvokers 就是上面我們緩存進去的 List
invokers = routerChain.route(getConsumerUrl(), invocation);
總結
在我們系統啟動時,已經緩存了註冊中心上的所有服務,後續的註冊中心掛了只會影響到後續則註冊,不會影響調用!
Dubbo分散式的RPC,微服務框架,
包括三個關鍵功能:基於介面的遠程調用,容錯與負載均衡,服務自動註冊與發現。
Dubbo使得調用遠程服務就像調用本地java服務一樣簡單。
參考Dubbo官方文檔:包括實現細節,遠程調用細節,服務提供者暴露服務。
主要流程。
1、provider向註冊中心去註冊
2、consumer從註冊中心訂閱服務,註冊中心會通知consumer註冊好的服務
3、consumer調用provider
4、consumer和provider都非同步的通知監控中心
基於zk作為註冊中心:
【提供者】在【啟動】時,向註冊中心zk 【註冊】自己提供的服務。
【消費者】在【啟動】時,向註冊中心zk 【訂閱】自己所需的服務。
所以是可以的,消費者在啟動時,消費者會從zk拉取註冊的生產者的地址介面等數據,緩存在本地。每次調用時,按照本地存儲的地址進行調用,消費者本地有一個生產者的列表,他會按照列表繼續工作,倒是無法從註冊中心去同步最新的服務列表,短期的註冊中心掛掉是不要緊的,但一定要儘快修復,掛掉是不要緊的,但前提是你沒有增加新的服務,如果你要調用新的服務,則是不能辦到的
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/279328.html