RPC就是把攔截到的方法參數,轉成可以在網絡中傳輸的二進制,并保證在服務提供方能正確地還原出語義,最終實現像調用本地一樣地調用遠程的目的。
1 RPC架構
RPC本質遠程調用,就要通過網絡來傳輸數據??紤]到可靠性,一般默認采用TCP協議。為屏蔽網絡傳輸復雜性,要封裝一個單獨的數據傳輸模塊收發(fā)二進制數據,即傳輸模塊。
用戶請求是基于方法調用,方法出入參數都是對象數據,要提前轉成二進制,即序列化過程。但只是把方法調用參數的二進制數據傳輸到服務提供方不夠,要在方法調用參數的二進制數據后增加“斷句”符,分隔出不同的請求,在兩個“斷句”符號中間放的內容就是請求的二進制數據,即協議封裝。
這兩個不同過程目的一樣,保證數據在網絡中正確傳輸:
數據能夠傳輸
傳輸后能正確還原出傳輸前的語義
可把這兩個處理過程放在架構中的同一個模塊,統稱為協議模塊。
還可在協議模塊加壓縮功能,壓縮過程也是對傳輸的二進制數據進行操作。在實際網絡傳輸過程中,請求數據包在數據鏈路層可能因太大而被拆分成多個數據包進行傳輸,為減少被拆分次數,導致整個傳輸過程時間太長,可在RPC調用時:在方法調用參數或者返回值的二進制數據大于某個閾值的情況下,我們可以通過壓縮框架進行無損壓縮,然后在另外一端也用同樣的壓縮算法進行解壓,保證數據可還原。
傳輸和協議兩模塊是RPC最基礎功能,它們使對象可正確傳輸到服務提供方。但距離RPC目標——實現像調用本地一樣調用遠程,還缺點。要讓這兩個模塊同時工作,要手寫一些黏合代碼,但這些代碼對使用RPC的研發(fā)無意義,且屬于一個重復工作,導致使用體驗不友好。
要在RPC里把這些細節(jié)對研發(fā)屏蔽,讓他們感覺不到本地調用和遠程調用區(qū)別。假設有用到Spring,希望RPC能讓我們把一個RPC接口定義成一個Spring Bean,并且這個Bean也會統一被Spring Bean Factory管理,可在項目中通過Spring依賴注入到方式引用。這是RPC調用的入口,一般叫Bootstrap模塊。
點對點(Point to Point)版本的RPC框架就完成了,一般這種模式的RPC框架為單機版,沒有集群能力。
集群能力:針對同一接口有多個服務提供者,但這多個服務提供者對調用方透明,所以在RPC里還要給調用方找到所有的服務提供方,并在RPC里維護好接口跟服務提供者地址的關系,調用方在發(fā)起請求時,才能快速找到對應接收地址,即“服務發(fā)現”。
但服務發(fā)現只解決接口和服務提供方地址映射關系查找,是一種“靜態(tài)數據”,對RPC來說,每次發(fā)送請求時都要用TCP連接的,相對服務提供方IP地址,TCP連接狀態(tài)瞬息萬變,所以RPC框架要有連接管理器去維護TCP連接狀態(tài)。
有了集群,提供方可能就需要管理好這些服務,RPC就要內置一些服務治理功能,如服務提供方權重的設置、調用授權等一些常規(guī)治理手段。而服務調用方需要額外做哪些事?每次調用前,都要根據服務提供方設置的規(guī)則,從集群中選擇可用的連接,以發(fā)送請求。
按分層設計原則,將這些功能模塊分為:
2 可擴展架構
RPC框架怎么支持插件化架構?可將每個功能點抽象成一個接口,將這個接口作為插件契約,然后把這個功能的接口與功能實現分離,并提供接口默認實現。
JDK自帶SPI可動態(tài)為某接口尋找服務實現,要在Classpath下的META-INF/services目錄創(chuàng)建一個以服務接口命名的文件,文件內容就是接口具體實現類。
JDK自帶SPI的缺陷
不能按需加載,ServiceLoader加載某接口實現類時,會遍歷全部獲取,即接口的實現類得全部載入并實例化,造成不必要浪費。
擴展如果依賴其它的擴展,就做不到自動注入和裝配,很難和其他框架集成,如擴展里面依賴了一個Spring Bean,原生Java SPI就不支持。
加上插件功能,RPC框架就包含了兩大核心體系——核心功能體系與插件體系:
整個架構就成了一個微內核架構,我們將每個功能點抽象成一個接口,將這個接口作為插件的契約,然后把這個功能的接口與功能的實現分離并提供接口的默認實現。
這樣的架構可擴展性好,實現開閉原則,用戶方便通過插件擴展實現功能,而且不需要修改核心功能本身
保持了核心包的精簡,依賴外部包少,有效減少開發(fā)人員引入RPC導致的包版本沖突問題。
3 總結
我們都知道軟件開發(fā)的過程很復雜,不僅是因為業(yè)務需求經常變化,更難的是在開發(fā)過程中要保證團隊成員的目標統一。我們需要用一種可溝通的話語、可“觸摸”的愿景達成目標,我認為這就是軟件架構設計的意義。
但僅從功能角度設計出的軟件架構并不夠健壯,系統不僅要能正確地運行,還要以最低的成本進行可持續(xù)的維護,因此我們十分有必要關注系統的可擴展性。只有這樣,才能滿足業(yè)務變化的需求,讓系統的生命力不斷延伸。
4 FAQ
① 使用jmeter進行壓力測試。jmeter官網中支持進行定制sampler取樣器,寫好的jar包放在lib\ext下,再啟動jmter時就能看到了。
插件化是一個概念,有很多種實現方式,這種也算。
② spring的spring.factories這一套也是利用的面向接口編程,感覺比jdk自帶的spi也好很多,既然有些問題,那為啥jdk的spi不優(yōu)化一下?
jdk我理解更多是標準。
③ jdk自帶spi一般會有一個接口加載很多實現類的情況嗎,因為只能用迭代器遍歷,導致只能用類型判斷才能找到自己想要的類,這樣感覺不夠優(yōu)雅吧,所以我感覺應該都是一個接口配置一個實現類這樣就是使用者想要的情況了。
那樣插件的意義就不存在了!
④ 業(yè)務為工業(yè)設備聯網數據采集,設備種類和型號繁多,產品中通過抽象出一套“驅動”的概念,把每類設備當作一個插件開發(fā),整體產品架構不變,感覺有點這個概念。只是產品還不夠大,其他插件體系還不夠明確
- [03-26]電纜溝蓋板吊環(huán)怎么安裝
- [02-18]電纜溝蓋板標準尺寸有哪幾種規(guī)格?
- [11-09]電纜溝蓋板吊環(huán)怎么安裝
- [03-27]電纜溝蓋板揭蓋計算
- [11-08]電纜溝的蓋板開啟后的正確使用方法
- [11-23]Rpc蓋板電纜溝蓋板材料哪種好?
- [11-27]山東電纜溝承重型蓋板
- [03-31]電纜溝蓋板鍍鋅方式分為冷鍍鋅和熱鍍鋅
- [08-27]RPC電纜溝蓋板的厚度標準是多少
- [08-17]電纜溝蓋板滿足什么特點
- [03-10]RPC活性粉末混凝土蓋板的發(fā)展
- [03-07]電纜溝蓋板在生產時需要注意哪些危險操作
- [03-06]RPC蓋板的蒸壓工藝
- [03-03]高鐵上的電纜溝槽為什么要用RPC蓋板?
- [03-02]超高性能混凝土的強度能達到多少?
- [02-27]關于電力蓋板出現凹陷的幾個原因
- [02-25]影響電纜溝蓋板壽命的因素,你知道有哪些?
- [02-24]復合井蓋相比于傳統井蓋有哪些優(yōu)點
- [02-19]RPC蓋板的環(huán)保措施有哪些
- [02-14]RPC蓋板環(huán)保措施有哪些呢