一。負載均衡與Ribbon
- 負載均衡,在集群中是很常見的一個“名詞”,顧名思義是根據一定的算法將請求分攤至對應的服務節點上,常見的算法有如下幾種:
- 輪詢法:所有請求被依次分發到每台應用服務器上,每台服務器需要處理的請求數目都相同,適合所有服務器硬件都相同的場景
- 隨機法:請求被隨機分配到各個應用服務器,在許多場合下,這種方案都很簡單實用。
- 源地址哈希(Hash)法:將請求來源的IP地址進行Hash計算,得到對應的服務器,這樣來自同一個IP的請求總在同一個服務器上處理
- 加權法:根據應用服務器配置的情況,按照權重將請求分發到每個服務器,當然高性能的服務器分配的權重更高
- 最小連接數(Least Connections)法:計算每個應用服務器正在處理的連接數,將新的請求分發到最少連接的服務器上,按理說,這是最符合負載均衡定義的算法
2. Ribbon是Netfix公司提供的一個負載均衡的客戶端框架,它可以和公司旗下的Eureka feign Hystrix等開源產品很好的集成,Ribbon框架具備以下特點:
-
- 負載均衡
- 容錯
- 多協議(HTTP, TCP, UDP)支持異步和反應模型。
- 緩存和批處理
二。Ribbon使用方式
1。首先我們定義服務(在這里就是order-server)注意在服務中的兩個配置文件
application.properties
#應用程序名稱 spring.application.name=order-server #指定config-server服務的地址 spring.cloud.config.uri=http://localhost:8888 #spring.profiles.active=local #取的是當前激活的環境 #spring.cloud.config.profile=${spring.profiles.active} spring.cloud.config.label=master #注冊中心地址 eureka.client.service-url.defaultZone=http://localhost:8000/eureka #服務端口號 server.port=8001 #management.endpoint.health.show-details=always #management.endpoint.hystrix.health.enabled=true # http://localhost:8888/{spring.application.name}/{spring.cloud.config.profile}/{label}
application-multi.properties
spring.application.name=order-server eureka.client.service-url.defaultZone=http://localhost:8000/eureka server.port=8011 management.endpoint.health.show-details=always management.endpoints.web.base-path=/ management.endpoints.web.exposure.include=health,beans,info # http://localhost:8888/{spring.application.name}/{spring.cloud.config.profile}/{label}
這里我們關注 spring.application.name配置 ,並設置不同的端口號
2。在idea里設置啟動類配置項
注意single instance only的復選框勾掉 active profiles 是設置當前激活的環境,配置完畢后啟動.OrderApplication服務兩次
3.新建一個項目ribbon-project並添加依賴
compile('org.springframework.cloud:spring-cloud-starter-netflix-ribbon')
4.在application.properties里添加配置項
order.ribbon.listOfServers=http://localhost:8001,http://localhost:8011 order.ribbon.connectTimeout=3000 order.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
注意:
- 這里面的格式定義:<client-name>.<namespace>.<property-value>=<value>,其中client-name代表客戶端名稱,今后我們會根據這個名字拿到客戶端對象。
- namespace默認的為ribbon的命名空間
- property-value我們可以參考:Enum CommonClientConfigKey 。其中listOfServers配置的是我們order-server的服務地址,當然我們也可以不做任何配置,那么此時ribbon會給我們設置默認的配置(可以參考:DefaultConfigClientImpl),如果不指定客戶端名稱,那么配置適用於所有客戶端。
- 我們可以指定負載均衡策略,其格式為:
<clientName>.<clientConfigNameSpace>.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.<className>className值:BestAvailableRule(),RandomRule(隨機) , RoundRobbinRule(輪詢) , WeightedResponseTimeRule(權重響應時間)
5.編寫客戶端請求代碼
package com.bdqn.lyrk.ribbon.study; import com.netflix.client.ClientFactory; import com.netflix.client.http.HttpRequest; import com.netflix.client.http.HttpResponse; import com.netflix.config.ConfigurationManager; import com.netflix.niws.client.http.RestClient; public class RibbonApplication { public static void main(String[] args) throws Exception { //加載配置文件 ConfigurationManager.loadPropertiesFromResources("application.properties"); RestClient restClient = (RestClient) ClientFactory.getNamedClient("order"); HttpRequest httpRequest = HttpRequest.newBuilder().uri("/orderId/1").build(); for (int i = 0; i < 5; i++) { HttpResponse response = restClient.executeWithLoadBalancer(httpRequest); System.out.println(response.getEntity(String.class)); } } }
6.服務端請參考:SpringCloud學習之Feign結尾的代碼示例
三。SpringCloud中的Ribbon
1) 使用@LoadBlanced注解和FeignClient
在RestTemplate上添加@LoadBlanced注解后,幕后英雄就成為了LoadBalancerClient,此時會創建LoadBalancerInterceptor的攔截器對象加入RestTemplate的攔截器棧中,大家可以自行了解下,具體的代碼示例如下:
@Bean @LoadBalanced RestTemplate restTemplate(){return new RestTemplate();}
2)使用DiscoveryClient
這個對象是spring給我們提供好的,我們通過@Autowired拿來用就是了。
3) @RibbonClient 與 @LoadBalanced
SpringCloud提供了@RibbonClient注解來創建自己定義的RibbonClient,初次接觸很容易與@LoadBalanced注解混淆,那么我在這里簡單解釋一下:
@LoadBalced主要標記在RestTemplate上,那么此時RestTemplate會使用RibbonLoadBalancerClient 來獲取服務
@RibbonClient 主要用於配置RibbonClient客戶端的,而且這個注解在我們服務發現中不是必須要配置的,如果我們使用SpringCloud中的服務發現機制,此時SpringCloud會給我們提供默認的Ribbon配置,甚至我們不需要配置@RibbonClient,不過當我們需要定義自己的RibbonClient或者不實用服務發現時,那么我們可以使用@RibbonClient注解
使用例子:
在我們的啟動類上添加如下注解
@RibbonClient(name = "myservice")
然后我們在application.properties做如下配置:
myservice.ribbon.eureka.enabled=false myservice.ribbon.listOfServers=http://localhost:5000, http://localhost:5001

