Ribbon负载均衡实现
1,在之前的博文中,我通过eureka,consul,zookeeper 实现了注册中心,在实现的服务发现过程中,都是通过RstTemplate 来实现RPC 远程调用
RestTemplate 封装了Httpclient 技术,遵循http 协议,同时还依赖了Ribbon,所以,在将RestTemplate 注入到spring 容器中的时候,必须加上@LoadBalanced 注解
@SpringBootApplication @EnableDiscoveryClient public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } @Bean // 注册到spring容器中 @LoadBalanced // 开启负载均衡 RestTemplate restTemplate() { return new RestTemplate(); } }
2,@LoadBalanced 注解的功能可以实现客户端负载均衡的作用,也就是说,如果访问的接口服务是集群的话,可以通过轮询的方式进行访问
3,通过 DiscoveryClient 可以实现Ribbon 本地负载均衡的效果,实现的话,RestTemplate 在注入的时候就不需要加上@LoadBalanced 的注解
@Bean // 注册到spring容器中 //@LoadBalanced // 开启负载均衡 RestTemplate restTemplate() { return new RestTemplate(); }
@RestController public class IndexMemberController { // 封装了http方法,显得更加的优雅 @Autowired private RestTemplate restTemplate; @Autowired private DiscoveryClient discoveryClient; private int requestCount = 1; @RequestMapping("/getOrder") public String getOrder() { // url会在eureka注册中心上通过别名进行查找,restTemplate通过别名来找服务,是依赖ribbon,所以RestTemplate初始化要加上@LoadBalanced String url = getUri(); if (url == null) { return "没有可用的接口"; } String orderUrl = url + "/getOrder"; String res = restTemplate.getForObject(orderUrl, String.class); System.out.println("rpc远程调用服务成功"); return res; } public String getUri() { List<ServiceInstance> instances = discoveryClient.getInstances("zk-order"); if (instances == null || instances.size() == 0) { return null; } int serverCount = instances.size(); int i = requestCount % serverCount; String uri = instances.get(i).getUri().toString(); requestCount++; return uri; } }
其实实现原理很简单,DiscoveryClient 获取到注册中心上指定的节点的所有的服务,获取之后,根据请求数目和服务的总数,做取模算法,达到轮询的效果。
Aimer,c'est partager