1、什么是Motan?
Motan是一套基於java開發的RPC框架,除了常規的點對點調用外,motan還提供服務治理功能,包括服務節點的自動發現、摘除、高可用和負載均衡等。Motan具有良好的擴展性,主要模塊都提供了多種不同的實現,例如支持多種注冊中心,支持多種rpc協議等。
2、微博開源框架Motan介紹
微博的Motan RPC服務,底層通訊引擎采用了Netty網絡框架,序列化協議支持Hessian和Java序列化,通訊協議支持Motan、http、tcp、mc等,Motan框架在內部大量使用,在系統的健壯性和服務治理方面,有較為成熟的技術解決方案,健壯性上,基於Config配置管理服務實現了High Availability與Load Balance策略(支持靈活的FailOver和FailFast HA策略,以及Round Robin、LRU、Consistent Hash等Load Balance策略),服務治理方面,生成完整的服務調用鏈數據,服務請求性能數據,響應時間(Response Time)、QPS以及標准化Error、Exception日志信息。
3、Motan提供的主要功能
服務發現 :服務發布、訂閱、通知
高可用策略 :失敗重試(Failover)、快速失敗(Failfast)、異常隔離(Server 連續失敗超過指定次數置為不可用,然后定期進行心跳探測)
負載均衡 :支持低並發優先、一致性 Hash、隨機請求、輪詢等
擴展性 :支持 SPI 擴展(service provider interface)
其他 :調用統計、訪問日志等
架構概述
Motan中分為服務提供方(RPC Server),服務調用方(RPC Client)和服務注冊中心(Registry)三個角色。
- Server提供服務,向Registry注冊自身服務,並向注冊中心定期發送心跳匯報狀態;
- Client使用服務,需要向注冊中心訂閱RPC服務,Client根據Registry返回的服務列表,與具體的Sever建立連接,並進行RPC調用。
- 當Server發生變更時,Registry會同步變更,Client感知后會對本地的服務列表作相應調整。
模塊概述
Motan框架中主要有register、transport、serialize、protocol幾個功能模塊,各個功能模塊都支持通過SPI進行擴展。
register
用來和注冊中心進行交互,包括注冊服務、訂閱服務、服務變更通知、服務心跳發送等功能;Server端會在系統初始化時通過register模塊注冊服務,Client端在系統初始化時會通過register模塊訂閱到具體提供服務的Server列表,當Server 列表發生變更時也由register模塊通知Client。
protocol
用來進行RPC服務的描述和RPC服務的配置管理,這一層還可以添加不同功能的filter用來完成統計、並發限制等功能。
serialize
將RPC請求中的參數、結果等對象進行序列化與反序列化,即進行對象與字節流的互相轉換;默認使用對java更友好的hessian2進行序列化。
transport
用來進行遠程通信,默認使用Netty nio的TCP長鏈接方式。
cluster
Client端使用的模塊,cluster是一組可用的Server在邏輯上的封裝,包含若干可以提供RPC服務的Server,實際請求時會根據不同的高可用與負載均衡策略選擇一個可用的Server發起遠程調用。
在進行RPC請求時,Client通過代理機制調用cluster模塊,cluster根據配置的HA和LoadBalance選出一個可用的Server,通過serialize模塊把RPC請求轉換為字節流,然后通過transport模塊發送到Server端。
配置概述
Motan框架中將功能模塊抽象為四個可配置的元素,分別為:
-
protocol:服務通信協議。服務提供方與消費方進行遠程調用的協議,默認為motan協議,使用hessian2進行序列化,netty作為Endpoint以及使用motan自定義的協議編碼方式。
-
registry:注冊中心。服務提供方將服務信息(包含ip、端口、服務策略等信息)注冊到注冊中心,服務消費方通過注冊中心發現服務。當服務發生變更,注冊中心負責通知各個消費方。
-
service:服務提供方提供的服務。使用方將核心業務抽取出來,作為獨立的服務。通過暴露服務並將服務注冊至注冊中心,從而使調用方調用。
-
referer:服務消費方對服務的引用,即服務調用方。
Motan推薦使用spring配置rpc服務,目前Motan擴展了6個自定義Spring xml標簽:
- motan:protocol
- motan:registry
- motan:basicService
- motan:service
- motan:basicReferer
- motan:referer
每種標簽的詳細含義請參考后文配置說明部分。全部參數清單請參考配置清單。
使用Motan
Motan主要使用Spring進行配置,業務代碼無需修改。關於在項目中使用Motan框架的具體步驟,請參考:快速入門。
在使用Motan框架時,除了配置之外還需要注意工程依賴及Motan框架本身的異常處理。
工程依賴
Motan框架采用模塊化設計,使用時可以按需依賴。目前的模塊有:
- motan-core
Motan核心框架 - motan-transport-netty
基於Netty協議的長連接傳輸協議 - motan-registry-consul
Consul服務發現組件 - motan-registry-zookeeper
Zookeeper服務發現組件 - motan-springsupport
Spring標簽解析相關功能
處理調用異常
-
業務代碼異常
當調用的遠程服務出現異常時,Motan會把Server業務中的異常對象拋出到Client代碼中,與本地調用邏輯一致。注意:如果業務代碼中拋出的異常類型為Error而非Exception(如OutOfMemoryError),Motan框架不會直接拋出Error,而是拋出包裝了Error的MotanServiceException異常。
-
MotanServiceException
使用Motan框架將一個本地調用改為RPC調用后,如果出現網絡問題或服務端集群異常等情況,Motan會在Client調用遠程服務時拋出MotanServiceException異常,業務方需要自行決定后續處理邏輯。 -
MotanFrameworkException
框架異常,比如系統啟動、關閉、服務暴露、服務注冊等非請求情況下出現問題,Motan會拋出此類異常。
協議與連接(motan:protocol)
介紹
Protocol用來配置Motan服務的協議。不同的服務適用不同的協議進行傳輸,可以自行擴展協議。
motan協議
Motan默認的rpc協議為motan協議,使用tcp長連接模式,基於netty通信。
負載均衡
Motan 在集群負載均衡時,提供了多種方案,缺省為 ActiveWeight,並支持自定義擴展。 負載均衡策略在Client端生效,因此需在Client端添加配置
目前支持的負載均衡策略有:
-
ActiveWeight(缺省)
低並發度優先: referer 的某時刻的 call 數越小優先級越高
由於 Referer List 可能很多,比如上百台,如果每次都要從這上百個 Referer 或者最低並發的幾個,性能有些損耗,因此 random.nextInt(list.size()) 獲取一個起始的 index,然后獲取最多不超過 MAX_REFERER_COUNT 的狀態是 isAvailable 的 referer 進行判斷 activeCount. -
Random
隨機,按權重設置隨機概率。
在一個截面上碰撞的概率高,但調用量越大分布越均勻,而且按概率使用權重后也比較均勻,有利於動態調整提供者權重。 -
RoundRobin
輪循,按公約后的權重設置輪循比率
-
LocalFirst
本地服務優先獲取策略,對referers根據ip順序查找本地服務,多存在多個本地服務,獲取Active最小的本地服務進行服務。
當不存在本地服務,但是存在遠程RPC服務,則根據ActivWeight獲取遠程RPC服務
當兩者都存在,所有本地服務都應優先於遠程服務,本地RPC服務與遠程RPC服務內部則根據ActiveWeight進行 -
Consistent
一致性 Hash,相同參數的請求總是發到同一提供者
-
ConfigurableWeight
權重可配置的負載均衡策略
容錯策略
Motan 在集群調用失敗時,提供了兩種容錯方案,並支持自定義擴展。 高可用集群容錯策略在Client端生效,因此需在Client端添加配置 目前支持的集群容錯策略有:
-
Failover 失效切換(缺省)
失敗自動切換,當出現失敗,重試其它服務器。
-
Failfast 快速失敗
快速失敗,只發起一次調用,失敗立即報錯。
連接控制
-
限制服務端連接池工作線程數
-
限制客戶端對每個服務建立的連接數
