问题引入:
在之前的Eureka案例中,我们启动了一个 服务调用者,获取了服务提供方实例信息,然后获取ip和端口号来访问,
而在实际应用环境中,我们会有多个服务提供方,形成集群。此时我们获取的服务列表中就会有很多个,
那我们应该访问哪一个?
我们本来应该写一个负载均衡算法,解决在多个服务列表中选择的问题。
但是!
Eureka中已经帮我们集成了负载均衡组件:Ribbon,我们简单的修改下代码就可以使用。
先来了解一下,什么是Ribbon:
Ribbon 是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的。为Ribbon配置 服务提供方 地址后,Ribbon就可基于某种负载均衡算法,自动地帮助 服务调用方 去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。(我们也可为Ribbon实现自定义的负载均衡算法)
下面,我们来使用Ribbon来实现一下负载均衡。
先要有两个服务提供方,我们可以参照 启动两个Eureka实例的方法来 启动两个服务提供方:
复制一个服务提供方实例
改名
改配置文件中的端口号后,启动复制的那个服务提供方实例:
启动完成后,我们就有两个服务提供方了,我们就可以取试试Ribbon复制均衡了。
- 引入Ribbon相关依赖。不过因为Eureka 默认集成了Ribbon,已经引入了 Ribbon 的依赖,所有不用我们手动引入。
- 覆盖默认配置。Ribbon 不用覆盖默认配置也可以用,所以这一步 我们也不用动。
- 在引导类里启用Ribbon:在引导类中的 restTemplate上加 @LoadBalanced 注解。
然后再将Controller中的代码修改一下:
下面我们 以Debug方式重启一下,服务调用方:
然后访问一下http://localhost/consumer/user?id=1,看看这样能否使用 服务提供方 的服务:
可以正常使用!
但是,使用的是哪一个 服务提供方 提供的服务呢?
我们来写个测试方法
@SpringBootTest
@RunWith(SpringRunner.class)
public class RibbonLBTest {
@Autowired
private RibbonLoadBalancerClient client;
@Test
public void test(){
for (int i = 0; i < 50; i++) {
ServiceInstance instance = this.client.choose("service-provider");
System.out.println(instance.getHost() + ":" + instance.getPort());
}
}
}
然后启动这个测试方式,看看输出:
我们能看到,服务调用方 轮询使用了 服务提供方!
Ribbon负载均衡,默认使用的是 轮询 的方式,我们也可以改变这种方式。
格式是:{服务名称}.ribbon.NFLoadBalancerRuleClassName: {负载均衡策略全路径(可自定义)}
我们来将负载均衡策略 改成 随机 方式试试。
在服务调用方的application.yml中 添加:
然后我们再启动一下测试方法看看:
负载均衡方式就变成了随机!