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 獲取到注冊中心上指定的節點的所有的服務,獲取之后,根據請求數目和服務的總數,做取模算法,達到輪詢的效果。