- Ribbon 介紹
Ribbon 是一個客戶端的負載均衡解決方案實現。它提供了我們很多已經實現好的負載方案,我們可以直接拿來用,或者自定義自己的負載均衡規則。Ribbon客戶端在啟動的時候會從Eureka Server端獲取它需要調用服務的列表,並且做緩存,所以在Ribbon客戶端啟動以后,即使Eureka服務出現問題或者停掉,只要調用的服務沒有問題,還是可以保證客戶端的正常調用,這樣做主要是為了保證CAP中的Availability。
- Ribbon 配置
這里我們為了演示輪詢的負載均衡方案,我們需要啟動兩個服務的provider,設置不同的端口,下面我們通過 Active profiles 來啟動服務,配置如下:
application-7011.yml
spring:
application:
name: provider-service
server:
port: 7011
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka01:7001/eureka/,http://eureka02:7002/eureka/,http://eureka03:7003/eureka/
application-7012.yml
spring:
application:
name: provider-service
server:
port: 7012
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka01:7001/eureka/,http://eureka02:7002/eureka/,http://eureka03:7003/eureka/
在啟動Application類中添加注解 @EnableDiscoveryClient,然后我們添加一個測試的Controllers類,代碼如下:
@RestController public class RibbonTest { @Autowired ApplicationContext applicationContext; @RequestMapping(value = "/provider/ribbon/printLog", method = RequestMethod.GET) public String printLog() throws UnknownHostException { String IPAddress = InetAddress.getLocalHost().getHostAddress(); String port = applicationContext.getEnvironment().getProperty("local.server.port"); return "Hello Provider ".concat(IPAddress).concat(":").concat(port); } }
至此,我們的provider service配置好了,接下來我們來配置 consumer service,首先我們需要在 pom.xml 添加 ribbon 依賴:
pom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
application.yml
spring:
application:
name: consumer-service
server:
port: 7021
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka01:7001/eureka/,http://eureka02:7002/eureka/,http://eureka03:7003/eureka/
添加 Ribbon 的配置類:
@Configuration // 如果多個服務可以選擇不同的策略 /*@RibbonClients({ @RibbonClient(name = "other",configuration = OtherConfig.class), @RibbonClient(name = "provider",configuration = ProviderConfig.class) })*/ @RibbonClient(name = "provider-service") public class RibbonConfig { //定義負載均衡規則 @Bean public IRule ribbonRule(){ return new RoundRobinRule(); } @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
這里我們主要介紹一下 Irule:
RoundRobinRule:輪詢規則
RandomRule:隨機規則
WeightedResponseTimeRule:使用響應時間的平均或者百分比為每個服務分配權重的規則,如果沒法收集響應時間信息,會默認使用輪詢規則
BestAvailableRule:會先根據斷路器過濾掉處於故障的服務,然后選擇並發量最小的服務
ZoneAvoidanceRule:根據server所在Zone和其性能,選擇服務器,默認規則
AvailabilityFilteringRule:先根據斷路器規則過濾掉有問題的服務,然后對剩余的服務按照輪詢的策略進行訪問
RetryRule:先按照RoundRobinRule規則進行服務獲取,如果調用服務失敗會在指定時間內進行重試,直到獲取到可用的服務。
Consumer service的Controller演示類:
@RestController public class RibbonTest { @Autowired private RestTemplate restTemplate; @GetMapping(value = "/consumer/ribbon/printLog") public String printProviderLog(){ String result = restTemplate.getForObject("http://provider-service/provider/ribbon/printLog", String.class); return result; } }
- 演示Ribbon的輪詢負載均衡
此時我們首先啟動的的Eureka服務,然后通過Active Profiles啟動兩個不同端口的provider service,最后啟動我們的consumer service,然后訪問 http://localhost:7021/consumer/ribbon/printLog ,然后不斷刷新,我們會看到端口7011和7012的不斷變化。