起源
如果在一個項目中有兩個
service
。
userService
和
orderService
。我們想要其中一個service調用另一個。

我們大概會有如下寫法:
public class userService{
private orderService orderService;
public User getOrder(Long orderId){
return orderService.getOrder(orderId);
}
}
随着業務的逐漸複雜,在開發中肯定會有業務拆分。初步是通過maven進行子產品的拆分。
不管maven如何拆分,都始終是在一個jvm中運作, 這樣隻是在代碼開發時會清楚友善一點。但是,某一個service在有較大壓力的情況下,沒有辦法單單對此service做出調整。最終,我們是想要userService和orderService在不同的jvm中運作,如果orderService通路較多,我們可以隻對它進行擴容。
如下圖,才是我們最終想要的方案,對于這種方案,orderService端,我們稱之為服務提供者,調用orderService的端,我們稱之為服務消費者。這種思想,也為dubbo的出現埋下了伏筆。
jvm的userService如何調用orderService呢?
在java遠端調用多年的沉澱,一個接着一個架構的出現,在一點點的優化這個調用的過程。
首先是socket調用。在orderService中開放socket服務,在userService中進行遠端調用。
優點:解決了單機調用的問題。
缺點:代碼複雜,不易于擴充。
這可能是最初的一個遠端調用解決方案,筆者不曾遇到過純socket調用的架構。
如何跨語言調用?
我們發現,在java的對象是不可以直接通過socket進行傳輸的,需要有一個序列化的過程。而且java的預設的序列化,是無法被其他語言解析的。這樣導緻如果有其他語言提供的服務,是無法通過java調用。是以對于socket進行了更新,通過http+xml進行資訊的傳輸。這就出現了webservice。
Web Service技術, 能使得運作在不同機器上的不同應用無須借助附加的、專門的第三方軟體或硬體, 就可互相交換資料或內建。依據Web Service規範實施的應用之間, 無論它們所使用的語言、 平台或内部協定是什麼, 都可以互相交換資料。
Web Service雖然早期很多人使用,但是到現在看來,這是一種過時的架構。因為,同樣的一些資料,通過json會比xml少很多。通過json會更少的占用帶寬。如下面資料。
如上圖,http協定在互動之前需要進行tcp三次握手,握手成功之後進行資料傳輸。一個http互動下來,有請求頭、請求體、響應頭、響應體。這些資料,在内部調用時,很多無關緊要的資料。也許可以自定義協定,簡化傳輸資料。這就出現了dubbo協定,一種内部調用的協定。
dubbo協定追求的是資料量小,小則快,協定的設計也符合dubbo框架構的理念,适用與内部服務之間的資料互動。安全性就沒有https做的那麼好,但是也不需要,畢竟dubbo協定設計的初衷就是内部使用的。
、一般開發一個服務需要多個機器進行部署,為了防止出現單點故障。對于一個較為完善的RPC架構來說,在多個機器提供同樣的一個服務的時候,需要自動做出選擇。好比上圖,userServuce在調用orderService的時候,需要自動識别叢集資訊,并且自動選擇機器進行調用。
目前,orderService隻有一個服務,三台機器,也許可以在userServuce中配置三個ip,然後自行編寫路由規則即可。但是随着業務的複雜,機器的變化,也許,我們起初無法得知機器的ip資訊。
為了實作動态的機器添加與移除。最終,添加了一個機器的協調者,所有開放服務的機器在這個協調者中添加自己的開放服務的資訊,這個協調者中會有哪些機器開放了哪些服務。這樣看來這個協調者類似一個"通訊錄"。我們稱這個"通訊錄"為注冊中心。
這樣一個較為完善的RPC架構,就有了雛形。
服務提供者啟動之後向注冊中心,送出自己提供服務的資訊。
服務消費者,在消費時,去注冊中心查詢是否有機器提供對應的服務。例如調用orderService時,可以發現有192.168.1.1和192.168.1.2機器有提供對應的服務。消費者可以根據随機、輪訓等規則選擇調用哪個服務。
在有服務上線或者下線時,注冊中心可以對修改的資訊進行通知。
這樣一套流程下來,就完美的實作的服務的動态部署,可以任意部署服務。
注冊中心的選擇
作為協調者的注冊中心,占據着一個重要地位。這樣來看,注冊中心主要實作了臨時資料存儲的功能。可以有多種選擇資料庫、redis、zookeeper、eureka、nacos、或者自己實作。
期初dubbo架構官方推薦使用zookeeper為注冊中心,出現nacos之後,逐漸從zookeeper轉為nacos。
其中的原因有很多,有興趣的小夥伴可以微信搜尋Java技術棧在曆史文章中搜尋閱讀。
為什麼zookeeper轉為nacos?結論為:zookeeper在大資料計算時做注冊中心是一個好的選擇,但是在服務調用時,也許資料不需要超強的一緻性。nacos是目前來說很友好的一個注冊中心,他提供了CP+AP。還有可視化界面,還有配置中心等功能。功能相當完善。
springcloud與dubbo的曆史
筆者不才,在17年時,這兩個詞才進入我的視線。當時還有一個超級火的springboot。那個時候招聘,幾乎每個崗位都要求會springboot。一時間,成為了一個java開發的必備功底。
由于springboot在大大開發了開發的速度,而且springcloud的各個元件都比較完善,feign、網關、配置中心、熔斷等等。spring、springcloud和springboot明顯是一家人。這讓一個孤身的dubbo有點不好立足,一些公司從dubbo架構轉為springcloud全家桶。
2018年7月份,eureka停止更新。 就目前來說eureka的功能單單作為注冊中心,已經足夠優秀了。但是對于節奏如此快的網際網路時代,停止更新,就意味着會慢慢的消失。
2019 年 7 月 24 日晚,Spring Cloud 官方釋出公告Spring Cloud Alibaba 即将畢業。提供了很多元件,對于大部分開發者而言,nacos、dubbo、seata應該是較為常用的元件。
nacos:注冊中心。
dubbo:一個基于Java的高性能開源RPC架構。
seata:一種高性能且易于使用的分布式事務解決方案,可用于微服務架構。
nacos是一個新推出的注冊中心,其中最亮眼的功能是提供了可視化界面,而且還附帶配置中心。瞬間dubbo就找到了家人。這些元件的出現讓dubbo又崛起了起來。而且dubbo本來擴充性就很好。可以進行協定擴充、調用攔截擴充、引用監聽擴充、叢集擴充等等。
另外dubbo3.0主力使用Triple 協定。完整相容 gRPC over HTTP/2。推薦使用 protobuf 作為預設序列化,在性能和跨語言上的效果都會更好。
結束語
就目前來看,dubbo架構是一個目前位置非常優秀的RPC架構, 一個必須要學的一個架構。也許以後它會更加優秀,也許會落寞。但是其設計思想,非常值得開發者去學習。