1. 程式人生 > >【圖解】我使用過的 Dubbo 和 Spring Cloud

【圖解】我使用過的 Dubbo 和 Spring Cloud

方便 分鐘 獨立開發 個人 walk 重啟 修改配置文件 高可用 開發

自從2015年畢業開始從事 Java 開發工作,已經過去3年多了, 在各種不知名的小公司待過,經歷過生產力從低到高,技術從落後到先進的過程, Dubbo 和 Spring Cloud 就是我曾經所經歷過的兩次技術變革。微服務這個概念已經出現好多年了,但是最近幾年微服務異常火爆,很多以前使用 Dubbo 的公司也在紛紛嘗試轉型。Dubbo 好還是 Spring Cloud 好,有啥差異,有啥優缺點是人們常常討論的話題,很多知名大V也紛紛寫一些科普文章,我也拜讀過很多,讀完感受良多,也激起了我寫這篇文章的動力。這篇文章更多的不是解釋概念,而是講述我曾經使用到的兩種技術的方式,希望大家可以從文章中獲得啟發。

原生狀態

如果以前關註過 Dubbo ,對 Dubbo 印象最深的一個定位就是 ”服務治理“的概念。為什麽要服務治理?服務治理到底治理了什麽方面?這是我們遇到的最直觀的問題。

下面就展示下我們曾經沒有使用 Dubbo 的業務模型:
技術分享圖片

大體的業務如下:

1、我們有項目A,和項目B,項目A由項目管理部負責使用,項目B由物流部負責使用;

2、每當項目管理部在項目A中完成一個項目,那麽就必須發請求給項目B,通知項目B進行物流發貨;

3、項目B物流完成之後給項目A發送一個請求,完成物流操作,告知項目A進入結算。

根據圖看的話,無非就是兩個項目互相調用,在沒用采用 Dubbo 之前,我們的項目結構就像圖中那樣混亂,很多問題都是不可避免的。下面我就把所有遇到的問題一一進行列舉,以項目A為例,:

1、開發者由於自身綜合素質不高,沒有良好編碼習慣和架構能力,對 webservice 的調用和服務暴露散落在各個層面如圖所示;

2、項目A中所有的請求的ip,寫在配置文件,如果項目B修改了部署ip或者端口,項目A需要手動修改配置文件然後重啟;

3、項目B如果修改了方法的參數和返回值,項目A無法得知;

4、項目A調用項目B使用的方式由於開發者的能力和經驗不同,采用的實現方式千奇百怪,有的使用 okhttp ,有的使用 Apache 的 HttpClient,有的使用原生的使用 Java 提供的原生操作。同樣,項目B中提供服務的方式也千奇百怪,有的是 Spring MVC 提供的 http 接口,有的使用的是 webservice,整個項目混亂不堪;

5、每個人寫的請求參數五花八門,比如超時時間設置,比如MediaType的設置等,沒有統一的規範;

6、當時接口是暴露在內網的,所以接口沒有做安全性校驗,但是這也是一大遺留問題。

Dubbo

當原生的架構出現了這些問題之後,我們需要對架構進行更新升級,綜合以前遇到的問題,我們提出了一些關於框架的需求:

1、調用其他服務的時候,不用手動的維護ip和端口;

2、暴露給其他服務的接口,接口形式要一致;調用其他服務的接口,方式要統一,參數統一設置,支持個別方法單獨設置參數;

3、采用RPC的形式,本地項目依賴遠程項目提供的sdk,調用sdk中的方法就可以實現遠程方法的調用。

在這樣的趨勢下,就很正常的選擇了 Dubbo 作為項目的框架,當時的想法也特別單純,和 Dubbo 當時的定位一樣,主要就是”服務治理“,讓混亂不堪的項目結構清晰起來。當時還沒有想到什麽分布式事務、服務熔斷、服務鑒權這些概念。我們使用 Dubbo 的時候, Dubbo 依然是停止更新狀態,還沒有捐獻給 Apache 。才采用 Dubbo 架構之後,我們對項目進行了整體的重構,同時引入了 SSO 的單點登錄,最後的架構大致如下:

技術分享圖片

修改之後的架構大概如下:

1、新增了 CAS 服務器作為統一認證,實現多項目的 SSO,保證登錄了一個系統之後,其他的系統也處於登錄狀態;

2、項目A和項目B,每個項目給對方提供一個 rpc-client 的包,裏面包含所提供的接口,公用的實體類等;

3、項目A和項目B,配置上增加 Dubbo 配置,比如註冊地址,序列化協議扥等 。一般都是采用 Dubbo 協議,認證到zookeeper中;

4、調用對方項目的接口時候,只需要註入 rpc-client 包中的類,調用其中的方法即可,dubbo會自動在zookeeper中查找服務註冊信息,發送請求,返回結構。

Spring Cloud

現在的公司架構采用的 Spring Cloud 微服務架構,平時自己也有學習和研究 Spring Cloud 相關的知識,自己對 Spring Cloud 的架構認識大概如下圖:

技術分享圖片

大概的架構如下:

1、用戶訪問Nginx,跳轉到前臺頁面;

2、當頁面有ajax請求時候,通過訪問nginx,nginx轉發到 Spring Cloud Gateway,然後根據路由規則轉發到具體的某個微服務中;

3、nacos作為服務註冊發現 + 動態配置 + 服務監控使用,這裏替代了 eureka + config + admin,其中config 項目,沒有可視化頁面,同時必須配合 Spring Cloud Bus + RabbitMQ通過訂閱消息才可以實現配置的動態刷新。是nacos一個項目融合了多個功能,如果以集群方式部署,大大節省了項目的數量,比如 eureka + config + admin 都要實現高可用,那麽需要至少 3*3個實例,而 nacos 只需要3個實例即可,同時降低項目復雜度。同時動態配置這塊nacos提供了可視化界面,並且有配置信息回滾等操作,簡單且功能強大 ;

4、每個微服務之間難免有服務的調用,比如支付服務在付款的時候,必須調用訂單服務,把訂單中商品的數量和價格等信息查詢過來,這裏使用的是 Feign ,每個微服務本身屬於 server 服務,給調用方提供一個 client 的sdk,當調用方使用 client 中的方法時候,就是實現了微服務之間的 Fegin 調用,同時配有 Hystrix 熔斷功能,防止接口長時間不返回,阻塞後續請求造成服務的連鎖奔潰反應。同時還包括有 Rbbion 的負載均衡和自動重試功能,某個服務無法訪問時候,自動進行切換並重試;

5、一次請求,可能涉及多個微服務,如果請求超時,那麽必須要能定位到哪一步的請求耗時過多,方便後續的優化修改,這時候就必須使用微服務的全鏈路追蹤,這裏使用了 Skywalking ,是因為 Skywalking 是通過字節碼增強技術實現,無須手動埋點,切性能較高。 Zipkin + Seluth 的組合,需要多個項目,同時 Zipkin 是通過 http 請求收集信息,性能較差;

6、其他的分布式事務、分布式主鍵發號器、分庫分表、緩存等方案就暫時不寫,主要就是為了表達下 Spring Cloud 架構下的 Java 項目結構。

總結

大部分情況下,說區別其實是個偽概念,因為 Dubbo 能實現的方式 Spring Cloud 也能實現, 反之亦然。下面所說的區別是針對我個人曾經經歷過的項目,個人所得出的感覺,歡迎不同觀點朋友的探討:

  • Dubbo
    • 項目結構:一般為前後一體化的項目為主,多以 JSP 為頁面技術;
    • 項目定位:每個項目一般稱之為一個系統,如 OA管理系統,BOSS系統等;
    • 團隊構成:Java Web 員工為主,前後臺都寫;
    • 使用群體:一般為公司內部員工及管理人員使用,受眾在百人與千人左右;
    • 性能要求:性能要求不高,高可用要求也不高,偶爾停機更新影響個5分鐘,半小時都不會有太大影響(額。。好像容易挨打);
    • 技術聚焦:采用 Dubbo 更多是出於服務治理的原因,就是為了解決原生架構中,服務調用的混亂和難以管理等問題。
  • Spring Cloud
    1. 項目結構: 微服務化,每個服務關於某個具體領域,每個項目擁有自己的數據庫。采用前後分離技術,前臺頁面關註於效果展示,頁面統一訪問網關,由網關根據路由規則轉發到具體的某個微服務中;
    2. 項目定位:每個項目稱之為微服務,只提供 http ( restful ) 接口,不負責頁面;
    3. 研發團隊:以微服務領域劃分,每個微服務應該有自己的團隊,獨立開發和維護,每個團隊盡可能將自己所負責的項目做到做好;
    4. 使用群體:以廣大用戶為主,人數成千上萬乃至億;
    5. 性能要求:一般微服務項目要求全年3個9(99.999%)或者4個9(99.9999%)高可用,微服務需要具備自動降級、故障切換、熔斷、在線擴容、重啟等功能;
    6. 技術聚焦:采用 Spring Cloud 架構,整個系統復雜度大幅度提升了,更多的是為在高並發和大流量下系統可以正常運行。

後記

由於本人經驗有限,經驗不足,文筆笨拙,文章寫的有點過於粗糙,以上分析和解釋可能還有錯誤和有失偏駁,還望大家批評指正。

【圖解】我使用過的 Dubbo 和 Spring Cloud