前言
上文介紹了SOFA-RPC 的幾種調用方式,包括單向調用、同步調用、Future調用、回調,引入了泛化調用和過濾器。本文將對 SOFA-RPC 的高級功能,包括參數配置、自定義線程池、預熱權重和自動故障剔除等。
正文
1. 參數配置
SOFABoot RPC Starter 提供了方便的參數設置方式。這些參數目前可以分為兩個部分。一部分是如端口,注冊中心地址等配置,這類配置在 application.properties 中。另一部分是如超時時間等配置,這類配置在 XML 中。
XML 配置
- 調用超時時間
如下是設置超時時間的方式,單位為 ms ,如果調用超過了這個時間則會拋出異常。服務端和客戶端都可以設置,以客戶端的超時時間設置優(yōu)先。默認客戶端為 3000 ,目前對 bolt,rest,dubbo 生效。
<sofa:binding.bolt>
<sofa:global-attrs timeout="5000"/>
</sofa:binding.bolt>
- 獲取地址等待時間
如下是設置獲取地址等待時間,單位為ms。在啟動時如果服務引用方等待超過了這個時間則不會再等待地址,會繼續(xù)啟動??蛻舳嗽O置,默認為-1,表示會一直等待到地址為止。目前對 bolt,rest 生效。
<sofa:binding.bolt>
<sofa:global-attrs address-wait-time="30000"/>
</sofa:binding.bolt>
- 建立連接超時時間
如下是設置建立連接超時時間,單位為 ms 。在建立連接時如果耗時超過了這個時間則會拋出異常??蛻舳嗽O,默認為 5000。目前對 bolt,rest 生效。
<sofa:binding.bolt>
<sofa:global-attrs connect.timeout="30000"
</sofa:binding.bolt>
- 權重
如下是設置權重。客戶端在發(fā)起調用時,如果采用的算法是隨機調用,則會根據該權重來進行隨機。服務端設置,默認為 100。目前對 bolt 生效。
<sofa:binding.bolt>
<sofa:global-attrs weight="200"/>
</sofa:binding.bolt>
- lazy 連接
默認情況下客戶端在注冊中心推送地址到客戶端時,就立即建立好連接,這個過程通常是在第一次調用之前進行的。如果設置服務引用的屬性 lazy 為 true,客戶端在第一次調用時才和所要調用的遠程地址建立連接。默認為 false。
如下設置 lazy 連接方式,將 lazy 屬性設為 true。目前支持 bolt 和 dubbo 協(xié)議。
<sofa:reference id="lazyServiceReferenceBolt" interface="com.ostenant.sofa.rpc.example.lazy.LazyService">
<sofa:binding.bolt>
<sofa:global-attrs lazy="true"/>
</sofa:binding.bolt>
</sofa:reference>
- check 屬性
默認情況下客戶端在啟動時,服務引用不要求存在可用的地址和連接。如果設置服務引用的屬性 check 為 true,客戶端在啟動時,服務引用會檢查是否存在對應的地址和連接,如果不存在會拋出異常。默認為 false。
如下設置 check 連接方式,將 check 屬性設為 true。目前支持 bolt 和 dubbo 協(xié)議。
<sofa:reference id="checkServiceReferenceBolt" interface="com.ostenant.sofa.rpc.example.check.CheckService">
<sofa:binding.bolt>
<sofa:global-attrs check="true"/>
</sofa:binding.bolt>
</sofa:reference>
- 重試次數
重試次數,即在第一次調用失敗后重試的最大次數,如果重試成功則不再繼續(xù)重試。默認為 0。如下設置調用次數,利用 retries 屬性指定重試次數。目前支持 bolt 和 dubbo 協(xié)議。
<sofa:reference id="retriesServiceReferenceBolt" interface="com.ostenant.sofa.rpc.example.retries.RetriesService">
<sofa:binding.bolt>
<sofa:global-attrs retries="2"/>
</sofa:binding.bolt>
</sofa:reference>
- 負載均衡
如下選擇負載均衡的方式,利用 loadBalancer 屬性指定調用時候使用的負載均衡策略,默認為 random。
目前支持 random,localPref,roundRobin,consistentHash,weightRoundRobin 五種負載均衡策略,具體可見 SOFARPC 負載均衡相關介紹。目前支持bolt協(xié)議。
<sofa:reference id="loadBalancerServiceReference" interface="com.ostenant.sofa.rpc.example.loadBalancer.LoadBalancerService">
<sofa:binding.bolt>
<sofa:global-attrs loadBalancer="random"/>
</sofa:binding.bolt>
</sofa:reference>
- 方法級別配置
如下,sofa:method 元素是方法級別的配置。方法級別的配置優(yōu)先級比服務級別的更高。name 屬性指定了方法的名字。支持調用超時時間,調用方式,回調類的設置。方法級別的配置與服務級別的配置所生效的協(xié)議一樣。
<sofa:binding.bolt>
<sofa:method name="sayMethod" timeout="3000" type="sync" callback-ref="xxx"/>
</sofa:binding.bolt>
Properties 配置
| 屬性 | 描述 | 默認值 | |
|---|---|---|---|
| spring.application.name | 應用名 | ||
| logging.path | 日志路徑 | ||
| logging.level.com.alipay.sofa.rpc.boot | sofa-rpc-boot-start的日志級別(starter自身的日志) | info | |
| logging.level.com.alipay.sofa.rpc | sofa-rpc的日志級別(sofa-rpc核心日志基本在這里) | info | |
| com.alipay.sofa.rpc.bolt.port | bolt 端口 | 22000 | |
| com.alipay.sofa.rpc.bolt.io.thread.count | bolt 的 io 線程數 | ||
| com.alipay.sofa.rpc.bolt.executor.thread.count | bolt 的業(yè)務線程最大值 | 200 | |
| com.alipay.sofa.rpc.bolt.accepts.count | bolt 能夠支持的最大長連接數 | 100000 | |
| com.alipay.sofa.rpc.rest.hostname | rest 的 hostname | ||
| com.alipay.sofa.rpc.rest.port | rest 端口 | 8341 | |
| com.alipay.sofa.rpc.rest.io.thread.count | rest 的 io 線程數 | cpu 核數 * 2 | |
| com.alipay.sofa.rpc.rest.executor.thread.count | rest 的業(yè)務線程數 | 200 | |
| com.alipay.sofa.rpc.rest.max.request.size | rest 的最大 byte 請求長度 | 1024 * 1024 * 10 | |
| com.alipay.sofa.rpc.rest.telnet | rest 是否支持 telnet | true | |
| com.alipay.sofa.rpc.rest.daemon | rest 是否支持 daemon | true | |
| com.alipay.sofa.rpc.dubbo.port | dubbo 的端口 | 20880 | |
| com.alipay.sofa.rpc.dubbo.io.thread.count | dubbo 的 io 線程數 | cpu 核數 + 1 | |
| com.alipay.sofa.rpc.dubbo.executor.thread.count | dubbo 的業(yè)務線程數 | 100 | |
| com.alipay.sofa.rpc.dubbo.accepts.count | dubbo能夠支持的最大長連接數 | 0,表示不限制 |
2. 自定義線程池
SOFA-RPC 支持自定義業(yè)務線程池??梢詾橹付ǚ赵O置一個獨立的業(yè)務線程池,和 SOFA-RPC 自身的業(yè)務線程池是隔離的,多個服務可以共用一個獨立的線程池。目前支持 bolt 協(xié)議。
在 SOFA-Boot 環(huán)境中可以為一個服務設置一個自定義線程池,配置如下:
- 聲明自定義線程池
如下聲明一個自定義線程池,class 必須為 com.alipay.sofa.rpc.server.UserThreadPool,這是 SOFA-RPC 提供的類,init-method="init" 也必須聲明以進行初始化。
<bean id="customerThreadPool" class="com.alipay.sofa.rpc.server.UserThreadPool" init-method="init">
<property name="corePoolSize" value="10"/>
<property name="maximumPoolSize" value="10"/>
<property name="queueSize" value="5"/>
<property name="threadPoolName" value="customerThreadPool_name"/>
</bean>
- 為服務設置自定義線程池
如下通過 sofa:global-attrs 元素的 thread-pool-ref 屬性為該服務設置自定義線程池。customerThreadPool 是上面自定義線程池的 bean id。
<bean id="threadPoolServiceImpl" class="com.ostenant.sofa.rpc.example.threadpool.ThreadPoolServiceImpl"/>
<sofa:service ref="threadPoolServiceImpl" interface="com.alipay.sofa.rpc.samples.threadpool.ThreadPoolService">
<sofa:binding.bolt>
<sofa:global-attrs thread-pool-ref="customerThreadPool"/>
</sofa:binding.bolt>
</sofa:service>
3. 預熱權重
SOFA-RPC 提供了預熱權重功能讓客戶端機器能夠根據服務端的相應權重進行流量的分發(fā)。目前支持 bolt 協(xié)議。
SOFA-Boot 中提供了一系列參數屬性,對指定服務進行預熱配置??蛻舳藱C器能夠自動解析這些參數,并按權重進行流量分發(fā)。
- warm-up-time: 服務的預熱時間
- warm-up-weight: 服務設置預熱期間權重
- weight: 服務設置預熱完后的權重
<sofa:reference id="sampleRestFacadeReferenceBolt" interface="com.alipay.sofa.endpoint.facade.SampleFacade">
<sofa:binding.bolt>
<sofa:global-attrs warm-up-time="10000" warm-up-weight="10" weight="100"/>
</sofa:binding.bolt>
</sofa:reference>
上述配置中,該服務的預熱期為10s,在預熱期內權重為10,預熱期結束后的正常權重為100。
如果該服務一共發(fā)布到A,B兩個機器上。A機器正處于預熱期內,使用上述配置;B已經完成預熱,正常權重為200。那么客戶端在調用的時候,此時流量分發(fā)的比重為10:200;A機器預熱結束后,流量分發(fā)比重為100:200。
4. 自動故障剔除
自動故障剔除會自動監(jiān)控 RPC 調用的情況,對故障節(jié)點進行權重降級,并在節(jié)點恢復健康時進行權重恢復。目前支持 bolt 協(xié)議。
在 SOFA-Boot 中,只需要將自動故障剔除的參數配置到 application.properties 即可。只配置自己關心的參數,其余參數會取默認值。需要注意的是,rpc.aft.regulation.effective 是該功能的全局開關,如果關閉則該功能不會運行,其他參數也都不生效。
- 自動故障剔除的配置參數意義
| 屬性 | 描述 | 默認值 | ||
|---|---|---|---|---|
| com.alipay.sofa.rpc.aft.time.window | 時間窗口大?。簩y(tǒng)計信息計算的周期。 | 10s | ||
| com.alipay.sofa.rpc.aft.least.window.count | 時間窗口內最少調用數:只有在時間窗口內達到了該最低值的數據才會被加入到計算和調控中。 | 10次 | ||
| com.alipay.sofa.rpc.aft.least.window.exception.rate.multiple | 時間窗口內異常率與服務平均異常率的降級比值:在對統(tǒng)計信息進行計算的時候,會計算出該服務所有有效調用ip的平均異常率,如果某個ip的異常率大于等于了這個最低比值,則會被降級。 | 6倍 | ||
| com.alipay.sofa.rpc.aft.weight.degrade.rate | 降級比率:地址在進行權重降級時的降級比率。 | 1/20 | ||
| com.alipay.sofa.rpc.aft.weight.recover.rate | 恢復比率:地址在進行權重恢復時的恢復比率。 | 2倍 | ||
| com.alipay.sofa.rpc.aft.degrade.effective | 降級開關:如果應用打開了這個開關,則會對符合降級的地址進行降級,否則只會進行日志打印。 | false(關閉) | ||
| com.alipay.sofa.rpc.aft.degrade.least.weight | 降級最小權重:地址權重被降級后的值如果小于這個最小權重,則會以該最小權重作為降級后的值。 | 0 | ||
| com.alipay.sofa.rpc.aft.degrade.max.ip.count | 降級的最大ip數:同一個服務被降級的ip數不能超過該值。 | 2 | ||
| com.alipay.sofa.rpc.aft.regulation.effective | 全局開關:如果應用打開了這個開關,則會開啟整個單點故障自動剔除摘除功能,否則完全不進入該功能的邏輯。 | false(關閉) |
- 配置示例
com.alipay.sofa.rpc.aft.time.window=20
com.alipay.sofa.rpc.aft.least.window.count=30
com.alipay.sofa.rpc.aft.least.window.exception.rate.multiple=6
com.alipay.sofa.rpc.aft.weight.degrade.rate=0.5
com.alipay.sofa.rpc.aft.weight.recover.rate=1.2
com.alipay.sofa.rpc.aft.degrade.effective=ture
com.alipay.sofa.rpc.aft.degrade.least.weight=1
com.alipay.sofa.rpc.aft.degrade.max.ip.count=2
com.alipay.sofa.rpc.aft.regulation.effective=true
上述配置中,默認打開了自動故障剔除功能和降級開關。當節(jié)點出現(xiàn)故障時會被進行權重降級,在恢復時會被進行權重恢復。
每隔 20s 進行一次節(jié)點健康狀態(tài)的度量,20s 內調用次數超過 30 次的節(jié)點才被作為計算數據。
如果單個節(jié)點的異常率超過了所有節(jié)點的平均異常率的 6 倍,則對該節(jié)點進行權重降級,降級的比率為 0.5。權重最小降級到 1。如果單個節(jié)點的異常率低于了平均異常率的 6 倍,則對該節(jié)點進行權重恢復,恢復的比率為1.2。單個服務最多降級 2 個 IP。
小結
本文介紹了 SOFA-RPC 的高級功能,包括參數配置,自定義線程池,服務預熱和自動降級與權重恢復等用法。對于 SOFA-RPC 提供的基本功能,以及整合 SOFA-Boot 的配置和用法就介紹完了。對此有了初步的認識后,有利于后續(xù)深入實現(xiàn)原理和剖析源碼。
歡迎關注技術公眾號: 零壹技術棧
本帳號將持續(xù)分享后端技術干貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分布式和微服務,架構學習和進階等學習資料和文章。