Ribbon
简介
Ribbon
是Netflix
发布的负载均衡器,它有助于控制 HTTP 和 TCP 的客户端的行为。为Ribbon
配置服务提供者地址后,Ribbon
就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon
默认为我们提供了很多负载均衡算法,例如轮询、随机等。当然,我们也可为 Ribbon 实现自定义的负载均衡算法。
为服务消费者整合Ribbon
启动一个
Eureka
注册中心,启动两个Eureka
服务提供者(参考传送门);创建服务消费者,在
pom
文件中添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 创建启动类:
// 添加注解,使其具备负载均衡能力
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerMovieRibbonApplication.class, args);
}
- 创建 Controller:
@RestController
public class MovieRibbonController {
private static final Logger LOGGER = LoggerFactory.getLogger(MovieRibbonController.class);
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class);
}
@GetMapping("/log-user-instance")
public void logUserInstance() {
ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
// 打印当前节点
MovieRibbonController.LOGGER.info(
"{}:{}:{}",
serviceInstance.getServiceId(),
serviceInstance.getHost(),
serviceInstance.getPort());
}
}
- 多次访问
http://127.0.0.1:8010/log-user-instance
,返回结果:
INFO 11146 --- [nio-8010-exec-2] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
INFO 11146 --- [nio-8010-exec-4] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9001
INFO 11146 --- [nio-8010-exec-6] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
INFO 11146 --- [nio-8010-exec-8] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9001
INFO 11146 --- [io-8010-exec-10] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
INFO 11146 --- [nio-8010-exec-2] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9001
INFO 11146 --- [nio-8010-exec-4] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
INFO 11146 --- [nio-8010-exec-7] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9001
INFO 11146 --- [nio-8010-exec-9] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
- 可以看到,请求会均匀分布到两个微服务节点上。
- 不能将
restTemplate.getForObject(...)
与loadBalancerClient.choose(...)
写在一个方法中,两者会有冲突——restTemplate
实际上是一个Ribbon
客户端,本身包含choose
的行为。
Ribbon
自定义配置
指定名称配置
- 创建
Ribbon
配置类:
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule() {
// 负载均衡改为随机
return new RandomRule();
}
}
- 创建空类:
@Configuration
@RibbonClient(name = "microservice-provider-user",configuration = RibbonConfiguration.class)
public class TestConfiguration {
}
- 多次访问
http://127.0.0.1:8010/log-user-instance
,返回结果:
INFO 11193 --- [nio-8010-exec-1] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
INFO 11193 --- [nio-8010-exec-3] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
INFO 11193 --- [nio-8010-exec-5] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9001
INFO 11193 --- [nio-8010-exec-7] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
INFO 11193 --- [nio-8010-exec-9] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9001
INFO 11193 --- [nio-8010-exec-1] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9000
INFO 11193 --- [nio-8010-exec-4] c.itmuch.consumer.MovieRibbonController : microservice-provider-user:192.168.200.104:9001
全局配置
- 可使用
@RibbonClients
注解提供默认配置:
@RibbonClients
public class RibbonClientDefaultConfigurationTestsConfig {
public static class BazServiceList extends ConfigurationBasedServerList {
public BazServiceList(IClientConfig config) {
super.initWithNiwsConfig(config);
}
}
}
class DefaultRibbonConfig {
@Bean
public IRule ribbonRule() {
return new BestAvailableRule();
}
@Bean
public IPing ribbonPing() {
return new PingUrl();
}
@Bean
public ServerList<Server> ribbonServerList(IClientConfig config) {
return new RibbonClientDefaultConfigurationTestsConfig.BazServiceList(config);
}
@Bean
public ServerListSubsetFilter serverListFilter() {
return new ServerListSubsetFilter();
}
}
使用属性自定义Ribbon
配置
NFLoadBalancerClassName
: 配置ILoadBalancer
的实现类。NFLoadBalancerRuleClassName
: 配置IRule
的实现类。NFLoadBalancerPingClassName
: 配置IPing
的实现类。NIWSServerListClassName
: 配置ServerList
的实现类。NIWSServerListFilterClassName
: 配置ServerListFilter
的实现类。
指定名称配置
microservice-provider-user:
ribbon:
NFLoadBalancerClassName: com.netflix.loadbalancer.RandomRule
全局配置
ribbon:
NFLoadBalancerClassName: com.netflix.loadbalancer.RandomRule