客戶端負載均衡:客戶端會有一個服務器地址列表,在發送請求前經過負載均衡算法選擇一個服務器,而後進行訪問。html
ribbon客戶端需配合zuul使用。git
# zuul 配置 zuul: routes: custom: # route key, 隨意,不重複便可 path: /target/page/** # 路由表達式 serviceId: customId # 客戶端id stripPrefix: false # 路由時保留 表達式前綴 # ribbon ribbon: eureka: enabled: false #不使用註冊中心
ribbon生成服務列表時,只會保留服務器地址+端口的信息,會忽略掉後面的路徑,故zuul配置stripPrefix=true
保留前綴以便路由到正確的地址。github
# ribbon 客戶端,名字與zuul裏serverId保持一致 customId: ribbon: # 服務端列表 listOfServers: http://localhost:8081,http://localhost:8081
優勢:經過簡單的配置,無需多餘的代碼便可生成客戶端,適合於客戶端服務列表穩定,且負載均衡不需特別定製的狀況。算法
缺點:客戶端負載使用ribbon默認的實現方式,不能知足特定的場景。spring
spring cloud 容許咱們經過註解配置來定製化客戶端,需去掉配置文件中關於ribbon客戶端的配置。服務器
@Configuration @RibbonClient(name = "customId", configuration = CustomConfiguration.class) public class TestConfiguration { }
一個名爲 customId 的客戶端將被生成,此配置不能被主運用程序上下文掃描到,需放到單獨的包中(筆者猜想配置多個客戶端的狀況下可能形成配置數據共享問題)。負載均衡
class CustomConfiguration{ @Bean public IRule ribbonRule() { return new BestAvailableRule(); } @Bean public IPing ribbonPing() { return new PingUrl(); } @Bean public ServerList<Server> ribbonServerList(){ //配置服務列表 Server[] serveArray = new Server[3]; serveArray[0] = (new Server("localhost", 9999)); ServerList<Server> serverServerList = new StaticServerList<>(serveArray); return serverServerList; } @Bean public ServerListSubsetFilter serverListFilter() { ServerListSubsetFilter filter = new ServerListSubsetFilter(); return filter; } }
優勢:經過少量的代碼,解決了負載均衡中特殊需求的定製化問題。ide
缺點:解決不了動態改變客戶端服務列表難題。源碼分析
ribbon在負載均衡中選擇服務須要讀取客戶端的服務列表信息,可經過clientId獲取負載均衡器並改變相關的配置信息,但ribbon的刷新機制默認是從配置中讀取數據,服務列表中的數據會被快速的替換掉。若咱們實現按需改變listOfServers
的配置,便可達到動態刷新客戶端服務列表的目的。spa
archius 的做用即爲動態改變配置。
public static void createRibbonClient(){ //設置:配置項 (ribbon 會讀取此配置) //根據 archaius 動態配置的特性 , 服務列表更新時只需從新賦值便可 ConfigurationManager.getConfigInstance().setProperty(CLIENT_ID + ".ribbon.listOfServers", LIST_SERVERS); // 獲取客戶端, 若不存在則建立 ClientFactory.getNamedClient(CLIENT_ID); // 負載均衡服務 DynamicServerListLoadBalancer serverListLoadBalancer = (DynamicServerListLoadBalancer) ClientFactory.getNamedLoadBalancer(CLIENT_ID); //根據需求定製化負載屬性: //輪詢方式、 Rule、 Ping 等 //serverListLoadBalancer.setPing(new PingUrl()); }
Client Side Load Balancer: Ribbon
Spring Cloud源碼分析(二)Ribbon
Archaius