ribbon作为客户端均衡器,在使用http调用服务端集群时,使用一定的策略帮助客户端选择一个服务端实例,进行真正的调用,达到客户端负载均衡的目的。
使用示例1:
maven中添加合适版本的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
添加Controller接口
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/allOrders/1")
public Object getOrders1() {
// order-service表示服务端服务名,选择一个服务
ServiceInstance serviceInstance = loadBalancerClient.choose("order-service");
// 根据选择出来的服务实例调用
String url = String.format("http://%s:%s/orders", serviceInstance.getHost(), serviceInstance.getPort());
return restTemplate.getForObject(url, String.class);
}
在配置文件中配置order-service
服务端所有实例
order-service.ribbon.listOfServers=\
localhost:8001,\
localhost:8002
服务端order-service提供/orders
接口实现
@Value("${server.port}")
private int port;
@Value("${spring.application.name}")
private String appName;
@GetMapping("/orders")
public Object getAllOrders() {
String result = "all orders list from : " + appName + ":" + port;
System.out.println(result);
return result;
}
调用客户端接口http://localhost:8888/allOrders/1
可得到调用了不同服务端的结果。
使用示例2:
通过注解的方式实现,在示例1的配置基础上只需要稍微改动代码
// 带负载均衡拦截器的RestTemplate
@LoadBalanced
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Autowired
private RestTemplate restTemplate;
@GetMapping("/allOrders/2")
public Object getOrders() {
// 自动负载均衡
return restTemplate.getForObject("http://order-service/orders", String.class);
}
同样,在配置文件中配置order-service
服务端所有实例
order-service.ribbon.listOfServers=\
localhost:8001,\
localhost:8002
ribbon忽略https配置
@Configuration
public class RibbonClientSpecificationConfig {
// 该bean会被注入到org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration#configurations字段
// 使用时被加载
@Bean
public RibbonClientSpecification ribbonClientSpecification() {
RibbonClientSpecification ribbonClientSpecification = new RibbonClientSpecification();
ribbonClientSpecification.setConfiguration(new Class[]{RibbonConfig.class});
ribbonClientSpecification.setName("default."+RibbonConfig.class.getName());
return ribbonClientSpecification;
}
}
// 使用ribbon是才会加载
public class RibbonConfig {
private OkHttpClient httpClient;
@Bean
public OkHttpClient client(OkHttpClientFactory httpClientFactory,
ConnectionPool connectionPool, IClientConfig config) {
RibbonProperties ribbon = RibbonProperties.from(config);
// 忽略https验证逻辑
this.httpClient = httpClientFactory.createBuilder(true)
.connectTimeout(ribbon.connectTimeout(), TimeUnit.MILLISECONDS)
.readTimeout(ribbon.readTimeout(), TimeUnit.MILLISECONDS)
.followRedirects(ribbon.isFollowRedirects())
.connectionPool(connectionPool)
.build();
return this.httpClient;
}
@PreDestroy
public void destroy() {
if (httpClient != null) {
httpClient.dispatcher().executorService().shutdown();
httpClient.connectionPool().evictAll();
}
}
}
具体https相关参见。