本文共 2243 字,大约阅读时间需要 7 分钟。
负载均衡之ribbon和RestTemplate
1.Ribbon
相较于Nginx,ribbon属于客户端负载,Nginx属于服务端负载,服务端负载是在服务之前做负载拦截,需要独立部署一个新服务。客户端负载是不需要独立部署的,客户端保存服务可用列表,使用负载算法,直接发起服务调用。(应用层无法使用客户端负载)
脱离eureka使用
@Autowired LoadBalancerClient loadBalancerClient; ServiceInstance orderservice = loadBalancerClient.choose("orderservice"); restTemplate.getForObject(String.format("http://%s:%d/orders",orderservice.getHost(), orderService.getPort()));
没有eureka的情况下,必须配置orderService.ribbon.listOfServers=localhost:8080,localhost:8081 ,ribbon才会有server供选择
原理
这里使用了懒加载,第一次调用choose的时候会为这个orderservice创建一个AnnotationConfigApplicationContext,注入了RibbonClientConfiguration.class所以,Ribbon的loadbalance会为每个serviceName创建一个Context,以及隔离的Client相关的bean**(NamedContextFactory.createContext)**
负载均衡的原理
真正的loadbalancer是ZoneAwareLoadBalancer
他的内部默认使用ZoneAvoidanceRule规则。 ZoneAvoidanceRule.choose()方法默认AbstractServerPredicate.chooseRoundRobinAfterFiltering:从数组取一个,下次取下一个 这是默认的策略,如果你要更改,那么你在配置文件配置rule的全路径名,重写他的choose方法:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule2.RestTemplate
RestTemplate其实就是封装了http请求,并且自动帮我们转换参数,以及返回值,他本身不具备负载均衡功能
3.具备负载均衡的RestTemplate
使用方法
@Autowired @LoadBalanced RestTemplate restTemplate; restTemplate.getForObject(String.format("http://orderService/orders");
原理
当加入了@LoadBalanced注解后,RestTemplate就具有了loadBalance的能力了,传入一个服务名,就可以根据这个名字从ribbon查找url
类LoadBalancerAutoConfiguration有以下代码:@LoadBalanced @Autowired(required = false) private ListrestTemplates = Collections.emptyList();
这里只会注入带有LoadBalanced注解的Restemplate
简单来说,在LoadBalancerAutoConfiguration中有个内部配置类RetryInterceptorAutoConfiguration。 他的restTemplateCustomizer 方法会返回一个RestTemplate的自定义化对象,这个对象目的只有一个,为RestTemplate设置一个ribbon的拦截器,这个拦截器其实会使用ribbonLoadbalanceClient的负载均衡功能,他就是RestTemplate可以负载的关键当restTemplates 不为空,就会注入拦截器,注入拦截器后,RestTemplate的requestFacory创建的request就会不一样,他会使用这个拦截器
3.restTemplate.getForObject 远程调用原理
委派 InterceptingClientHttpRequest.execute()
委派 LoadBalancerInterceptor.intercept() 最后 RibbonLoadbalancerClient.execute: 选一个server,执行httpRequest搭配Eureka
DynamicServerListLoadBalancer:初始化会调用
restOfInitenableAndInitLearnNewServersFeature() //定时刷新serverList updateListOfServers() //手动更新一次
他们也是通过获取到DiscoverClient与eureka通信的
总结,本质上来说,就是ribbon具有负载均衡的能力,RestTemplate想要有,就在调用链路想办法注入他(拦截器)
转载地址:https://blog.csdn.net/qq_31543867/article/details/112146630 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!