你要的负载均衡Ribbon,来了

大家好,我是阿七 。
在上一篇文章中,我们已经实现了内容中心总能够调用用户中心,那如何实现负载均衡呢?请听阿七为你娓娓道来 。(没看到上篇文章的同学请戳这里:实战(一)nacos注册与发现)
一、负载均衡的两种方式众所周知,在负载均衡领域一般有两种方式去实现,分别是:
1、服务器端负载均衡;
2、客户端侧负载均衡;
在单体架构时代,我们一般会部署多个实例在服务器上,然后使用Nginx做负载均衡(nginx也是部署在服务器上的) 。请求全部打在nginx上,nginx根据负载均衡策略将请求转发到不同的实例上 。如下面这幅图所示:

你要的负载均衡Ribbon,来了

文章插图
 
有同学会疑问了,为什么nginx可以抗住这么多的请求呢?因为它异步,非阻塞,使用了epoll 和大量的底层代码优化,哈哈跑题了,阿七后面再专门写文章说说nginx 。
说完了服务器端负载均衡,那么什么是客户端负载均衡呢?且看下图:
你要的负载均衡Ribbon,来了

文章插图
 
在这幅图中,内容中心是要调用用户中心的,那么内容中心相对于用户中心就是客户端,对吧,这个应该可以理解 。现在我们已经可以通过DiscoveryClient来获取用户中心的多个实例,如果我们在内容中心自己写一个负载均衡规则,然后交给RestTemplate来请求一个用户中心实例,这样就实现了客户端负载均衡了 。说干就干,咱这就来写一个负载均衡策略 。
二、手写一个客户端负载均衡器第一步,修改代码:之前是调用findFirst()默认返回第一个用户中心实例,现在注释掉了,改成随机获取一个用户中心实例 。
public ShareDTO findById(Integer id) {Share share = this.shareMApper.selectByPrimaryKey(id);Integer userId = share.getUserId();//用户中心的所有实例信息List<ServiceInstance> instances = discoveryClient.getInstances("user-center");//String targetUrl = instances//.stream()//.map(instance -> instance.getUri().toString() + "/users/{id}")//.findFirst()//.orElseThrow(() -> new IllegalArgumentException("当前没有实例对象"));List<String> targetUrls = instances.stream().map(instance -> instance.getUri().toString() + "/users/{id}").collect(Collectors.toList());//随机算法int i = ThreadLocalRandom.current().nextInt(targetUrls.size());String targetUrl = targetUrls.get(i);log.info("请求的目标地址:{}",targetUrl);//根据userId查询用户信息UserDTO userDTO = this.restTemplate.getForObject(targetUrl, UserDTO.class, userId);ShareDTO shareDTO = new ShareDTO();BeanUtils.copyProperties(share, shareDTO);shareDTO.setWxNickname(userDTO.getWxNickname());return shareDTO;}第二步,测试:
1、我们先启动一个用户中心实例,端口为8888;然后修改端口号为8887,点击Edit Configurations,勾选Allow parallel run,保存,再启动一次项目,这样就可以启动两个用户中心实例 。如下图:
你要的负载均衡Ribbon,来了

文章插图
 
2、启动内容中心实例,打开nacos看看
你要的负载均衡Ribbon,来了

文章插图
 
3、接口测试,访问http://localhost:8889/shares/1
你要的负载均衡Ribbon,来了

文章插图
 
这时,我们去控制台看看:
你要的负载均衡Ribbon,来了

文章插图
 
哎,我们会发现,内容中心在随机调用用户中心的实例 。说白了,负载均衡器就是给你一个list,你随机从中获取一个实例来调用 。 但是我们这个代码还是比较简单的,只是模拟一下 。如果我们每次进行服务调用都写这么一堆代码肯定也是不现实的 。
那么下面我们就要ribbon进行重构咯,同学们继续往下看 。
三、整合ribbon在使用ribbon进行重构之前,我们肯定得了解什么是ribbon对吧 。一句话阐述ribbon是Netflix开源的客户端侧负载均衡器 。 其实,ribbon就是我们刚刚写的代码的一个组件,但是它封装的更好,提供了更多的负载均衡策略 。
下面我们就来整合ribbon到我们的项目中 。还记得三步骤吗?
第一步加依赖:因为nacos-discovery中已经集成了netflix-ribbon,所以这里就不要在单独集成了 。
你要的负载均衡Ribbon,来了

文章插图
 
第二步加注解:在RestTemplate上加注解@LoadBalanced
@MapperScan("com.seven")@SpringBootApplicationpublic class ContentCenterApplication {public static void main(String[] args) {SpringApplication.run(ContentCenterApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}}


推荐阅读