序言
Ribbon 是一個客戶端負載均衡器(Nginx 為服務端負載均衡),它賦予了應用一些支配 HTTP 與 TCP 行為的能力,可以得知,這里的客戶端負載均衡也是進程內負載均衡的一種。它在 Spring Cloud 生態內是一個不可缺少的組件,少了它,服務便不能橫向擴展,這顯然是有違雲原生12要素的。此外 Feign 與 Zuul 中已經默認集成了 Ribbon,在我們的服務之間凡是涉及調用的,都可以集成它並應用,從而使我們的調用鏈具備良好的伸縮性。
附帶拓展福利,雲原生12要素:https://12factor.net/zh_cn/
Ribbon是Netflix公司開源的一個負載均衡的項目,它屬於上述的第二種,是一個客戶端負載均衡器,運行在客戶端上。它是一個經過了雲端測試的IPC庫,可以很好地控制HTTP和TCP客戶端的一些行為。 Feign已經默認使用了Ribbon。
- 負載均衡
- 容錯
- 多協議(HTTP,TCP,UDP)支持異步和反應模型
- 緩存和批處理
ribbon:https://github.com/Netflix/ribbon
Feign集成Ribbon示例
@RestController @RequestMapping(value = "/Promotion",method = RequestMethod.GET) public class PromotionController implements PromotionFacade { @Value("${server.port}") String port; @Value("${spring.profiles.active}") String environment; @Override @RequestMapping(value = "/delete") public String releasePromotion(@RequestParam int orderID){ try { if ("local".equals(environment)) { Thread.sleep(200L); } return port; } catch (Exception ex) { return port+"---"+ex.getMessage(); } } }
注冊服務如下
上述trade-promotion服務,有2個站點部署,feign調用他們如下。
@FeignClient(name = "trade-promotion") public interface PromotionClient { @RequestMapping(value = "/Promotion/delete", method = RequestMethod.GET) String releasePromotion(@RequestParam int orderID); }
默認情況下,調用結果是:8085,8082,8085,8082,8085,8082,8085,8082... 這樣輪詢調用執行。
原因就是默認集成啦Ribbon,可以通過spring-cloud-starter-openfeign這個依賴看下他的父依賴中,就有spring-cloud-starter-netflix-ribbon這個包的依賴。
Ribbon的負載均衡策略
- RandomRule (隨機策略): 隨機選擇 Server
- RoundRobinRule (輪訓策略): 按順序循環選擇 Server
- RetryRule (重試策略): 在一個配置時問段內當選擇 Server 不成功,則一直嘗試選擇一個可用的 Server
- BestAvailableRule (最低並發策略): 逐個考察 Server,如果 Server 斷路器打開,則忽略,再選擇其中並發連接最低的 Server
- AvailabilityFilteringRule (可用過濾策略): 過濾掉一直連接失敗並被標記為 circuit tripped 的 Server,過濾掉那些高並發連接的 Server(active connections 超過配置的網值)
- ResponseTimeWeightedRule (響應時間加權策略): 根據 Server 的響應時間分配權重。響應時間越長,權重越低,被選擇到的概率就越低;響應時間越短,權重越高,被選擇到的概率就越高。這個策略很貼切,綜合了各種因素,如:網絡、磁盤、IO等,這些因素直接影響着響應時間
- ZoneAvoidanceRule (區域權衡策略): 綜合判斷 Server 所在區域的性能和 Server 的可用性輪詢選擇 Server,並且判定一個 AWS Zone 的運行性能是否可用,剔除不可用的 Zone 中的所有 Server
默認為輪詢策略
全局策略設置
@Configuration public class RibbonConfig { /** * 隨機規則 */ @Bean public IRule ribbonRule() { return new RetryRule(); } }
配置文件配置
#trade-promotion:這個是eureka中的被調用的服務名稱
trade-promotion.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
note:第一個new的對象與上面的輪詢規則匹配,第二個配置文件最后的詞語也是與輪詢規則匹配
Ribbon 超時與重試
針對單個服務的重試與超時配置:
#負載均衡策略
trade-promotion.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
#http建立socket超時時間,毫秒
trade-promotion.ribbon.ConnectTimeout=2000
#http讀取響應socket超時時間
trade-promotion.ribbon.ReadTimeout=5000
#同一台實例最大重試次數,不包括首次調用
trade-promotion.ribbon.MaxAutoRetries=0
#重試負載均衡其他的實例最大重試次數,不包括首次server
trade-promotion.ribbon.MaxAutoRetriesNextServer=2
# 是否所有操作都重試,POST請求注意多次提交錯誤。
# 默認false,設定為false的話,只有get請求會重試
trade-promotion.ribbon.OkToRetryOnAllOperations=true
全局服務的重試與超時配置
#http建立socket超時時間,毫秒
ribbon.ConnectTimeout=2000
#http讀取響應socket超時時間
ribbon.ReadTimeout=5000
#同一台實例最大重試次數,不包括首次調用
ribbon.MaxAutoRetries=0
#重試負載均衡其他的實例最大重試次數,不包括首次server
ribbon.MaxAutoRetriesNextServer=2
# 是否所有操作都重試,POST請求注意多次提交錯誤。
# 默認false,設定為false的話,只有get請求會重試
ribbon.OkToRetryOnAllOperations=true
Ribbon脫離Eureka進行負載
ribbon.eureka.enabled=false
trade-promotion.ribbon.listOfServers:http://localhost:8085,http://localhost:8082
Ribbon飢餓加載
ribbon.eager-load.enabled=true
ribbon.eager-load.clients=trade-promotion,trade-order
總結
多看文檔,多翻資料