Ribbon 实现客户端负载均衡的基础:Ribbon通过 DiscoveryClient从Eureka上获取注册的服务列表
如何使用 DiscoveryClient 获取服务实例信息:
获取当前注册到 Eureka 中的服务名称列表
List<String> serviceNames = discoveryClient.getServices();
服务名称列表可以获取所有自己感兴趣的服务,并进一步获取这些服务的实例信息
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName);
ServiceInstance 对象代表服务实例如下
public interface ServiceInstance {
//服务实例的唯一性 Id
String getServiceId();
//主机
String getHost();
//端口
int getPort();
//URI
URI getUri();
//元数据
Map<String, String> getMetadata();
…
}
显然服务实例中的属性(IP,PORT,URL)可以让我们轻松的访问到目标服务,此时你可以选择负载均衡策略来控制如何发送HTTP请求的策略。
通过 @Loadbalanced 注解调用服务
默认情况下,Ribbon 使用的是轮询策略
@SpringBootApplication
@EnableEurekaClient
public class RibbonApplication {
@LoadBalanced
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonApplication .class, args);
}
}
往容器里注入被@LoadBalanced修饰的restTemplate 此时容器中的RestTemplate 已经具备了客户端负载均衡功能 ,在调用的地方使用restTemplate.exchange就可以了。
通过 @RibbonClient 注解自定义负载均衡策略
更加精细化的控制
public @interface RibbonClient {
//同下面的 name 属性
String value() default "";
//指定服务名称
String name() default "";
//指定负载均衡配置类
Class<?>[] configuration() default {};
}
我们需要创建一个独立的配置类,用来指定具体的负载均衡规则,演示如下
@Configuration
public class SpringTestBalanceConfig{
@Autowired
IClientConfig config;
@Bean
@ConditionalOnMissingBean
public IRule springTestRule(IClientConfig config) {
return new RandomRule();
}
}
使用 RandomRule(随机访问策略) 替换 Ribbon 中的默认负载均衡策略 RoundRobin(轮询策略)。我们可以根据需要返回任何自定义的 IRule 接口的实现策略,以下是IRule接口的实现
负载均衡配置类的使用方法
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "userservice", configuration = SpringTestLoadBalanceConfig.class)
public class TestApplication{
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
可以注意到,我们在 @RibbonClient 中设置了目标服务名称为 userservice,配置类为 SpringTestLoadBalanceConfig。现在每次访问 user-service 时将使用 RandomRule 这一随机负载均衡策略。
对比 @LoadBalanced 注解和 @RibbonClient 注解,如果使用的是普通的负载均衡场景,那么通常只需要 @LoadBalanced 注解就能完成客户端负载均衡。而如果我们要对 Ribbon 运行时行为进行定制化处理时,就可以使用 @RibbonClient 注解。