nginx负载均衡原理 服务器负载均衡是什么意思( 三 )


2.2.4.多个服务实例,如何负载均衡上述案例中,我们获取到的实例是两个,那么每次调用的时候,我们怎么来确定,我要调用的是哪一个服务?,因为这时候我们拿到的两个服务,也就是两个不同的IP地址,这时候就需要一个负载均衡器来帮我们选择一个IP进行访问 。
在Spring Cloud中,netfix提供一个负载均衡器Ribbon,该负载均衡器是声明式的,其用法如下所示,在我们注入到Spring容器中的RestTemplate添加注解@LoadBalanced,这时候我们的RestTemplate就具备了负载均衡的功能 。

注意:RestTemplate底层默认使用的jdk的标准实现,如果我们想让RestTemplate的底层使用okhttp,可以替换实现的 。如下源码所示,RestTemplate提供了三个构造方法 。
我们可以使用上述的第二个构造方法,使用Okhttp 。
@SpringBootConfigurationpublic class RestTemplateConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}}在上面的一个案例中,我们通过从服务实例中,获取到服务,然后再从服务中心获取具体的IP地址信息,发起请求 。
String url = serviceInstance.getHost() + ":" + serviceInstance.getPort();Items items = restTemplate.getForObject("http://" + url + "/itemservice/item/1" ,但是,现在我们不需要这么做了,因为我们对restTemplate声明了是需要负载均衡的,因此我们发起请求的时候,就不需要指定IP地址了,我们可以用服务ID来代替IP地址,然后由restTemplate来帮我选择需要调用的IP 。因此上述代码会被简化为如下所示,被注释掉的代码就是被优化的代码 。
@GetMapping(value = "https://www.520longzhigu.com/shenghuo/order/{orderId}") public Order queryOrderById(@PathVariable("orderId") String orderId) {String serviceId = "hutao-microservice-item";//List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);//ServiceInstance serviceInstance = instances.get(0);//String url = serviceInstance.getHost() + ":" + serviceInstance.getPort();//Items items = restTemplate.getForObject("http://" + url + "/itemservice/item/1" , Items.class);Items items = restTemplate.getForObject("http://" + serviceId + "/itemservice/item/1" , Items.class);System.out.println(items);return null; }重启服务后,商品服务仍然可用,那么这时候怎么来验证我们的负载均衡成功了?
2.2.5.简单验证负载均衡其实最简单的验证方式就是,在商品服务中,添加日志,看看哪个服务记录了日志或者debug调试,看走哪一个服务的代码 。即可验证我们的负载均衡是否成功 。
当然这里我们就不做上述方式的演示,来做一点高难度的代码分析 。
3.分析@LoadBalanced实现负载均衡源码解析3.1.RestTemplate源码解析1、首先看org.springframework.web.client.RestTemplate类 。
当我们执行如下代码时
restTemplate.getForObject("http://" + serviceId + "/itemservice/item/1" , Items.class);最终会执行到如下方法
doExecute(URI, HttpMethod, RequestCallback, ResponseExtractor<T>)如上代码根据我们的提供的信息,创建了ClientHttpRequest请求, 我们发现doExecute有如下几个实现,这里由于我们使用的是默认的RestTemplate,因此我们查看org.springframework.http.client.AbstractClientHttpRequest这个类的org.springframework.http.client.AbstractClientHttpRequest.execute()方法 。
3.2.LoadBalancerInterceptor源码解析逐步深入代码,我们找到了如下的拦截器 。LoadBalancerInterceptororg.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor
3.3.RibbonLoadBalancerClient源码解析继续深入代码,我们找到了RibbonLoadBalancerClient这个类org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient通过查看代码,我们发现了getLoadBalancer(String)这个方法通过serviceId找到了两个服务实例,


以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!

「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助: