一、什麼是Motan?java
Motan是一套基於java開發的RPC框架,除了常規的點對點調用外,motan還提供服務治理功能,包括服務節點的自動發現、摘除、高可用和負載均衡等。Motan具備良好的擴展性,主要模塊都提供了多種不一樣的實現,例如支持多種註冊中心,支持多種rpc協議等。git
二、微博開源框架Motan介紹github
微博的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日誌信息。spring
三、Motan提供的主要功能服務器
服務發現 :服務發佈、訂閱、通知
高可用策略 :失敗重試(Failover)、快速失敗(Failfast)、異常隔離(Server 連續失敗超過指定次數置爲不可用,而後按期進行心跳探測)
負載均衡 :支持低併發優先、一致性 Hash、隨機請求、輪詢等
擴展性 :支持 SPI 擴展(service provider interface)
其餘 :調用統計、訪問日誌等網絡
Motan中分爲服務提供方(RPC Server),服務調用方(RPC Client)和服務註冊中心(Registry)三個角色。架構
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
Motan主要使用Spring進行配置,業務代碼無需修改。關於在項目中使用Motan框架的具體步驟,請參考:快速入門。
在使用Motan框架時,除了配置以外還須要注意工程依賴及Motan框架自己的異常處理。
Motan框架採用模塊化設計,使用時能夠按需依賴。目前的模塊有:
業務代碼異常
當調用的遠程服務出現異常時,Motan會把Server業務中的異常對象拋出到Client代碼中,與本地調用邏輯一致。
注意:若是業務代碼中拋出的異常類型爲Error而非Exception(如OutOfMemoryError),Motan框架不會直接拋出Error,而是拋出包裝了Error的MotanServiceException異常。
MotanServiceException
使用Motan框架將一個本地調用改成RPC調用後,若是出現網絡問題或服務端集羣異常等狀況,Motan會在Client調用遠程服務時拋出MotanServiceException異常,業務方須要自行決定後續處理邏輯。
MotanFrameworkException
框架異常,好比系統啓動、關閉、服務暴露、服務註冊等非請求狀況下出現問題,Motan會拋出此類異常。
Protocol用來配置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 快速失敗
快速失敗,只發起一次調用,失敗當即報錯。
鏈接控制
限制服務端鏈接池工做線程數
限制客戶端對每一個服務創建的鏈接數