LoadBalancer 负载均衡
前面我们讲解了如何对服务进行拆分、如何通过Eureka服务器进行服务注册与发现,那么现在我们来看看,它的负载均衡到底是如何实现的,实际上之前演示的负载均衡是依靠LoadBalancer实现的。
在2020年前的SpringCloud版本是采用Ribbon作为负载均衡实现,但是2020年的版本之后SpringCloud把Ribbon移除了,进而用自己编写的LoadBalancer替代。
那么,负载均衡是如何进行的呢?
负载均衡
实际上,在添加@LoadBalanced
注解之后,会启用拦截器对我们发起的服务调用请求进行拦截(注意这里是针对我们发起的请求进行拦截),叫做LoadBalancerInterceptor
,它实现ClientHttpRequestInterceptor
接口:
@FunctionalInterface
public interface ClientHttpRequestInterceptor {ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException;
}
主要是对intercept
方法的实现:
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {URI originalUri = request.getURI();String serviceName = originalUri.getHost();Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
}
我们可以打个断点看看实际是怎么在执行的,可以看到:
服务端会在发起请求时执行这些拦截器。
那么这个拦截器做了什么事情呢,首先我们要明确,我们给过来的请求地址,并不是一个有效的主机名称,而是服务名称,那么怎么才能得到真正需要访问的主机名称呢,肯定是得找Eureka获取的。
我们来看看loadBalancer.execute()
做了什么,它的具体实现为BlockingLoadBalancerClient
:
//从上面给进来了服务的名称和具体的请求实体
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {String hint = this.getHint(serviceId);LoadBalancerRequestAdapter<T, DefaultRequestContext> lbRequest = new LoadBalancerRequestAdapter(request, new DefaultRequestContext(request, hint));Set<LoadBalancerLifecycle> supportedLifecycleProcessors = this.getSupportedLifecycleProcessors(serviceId);supportedLifecycleProcessors.forEach((lifecycle) -> {lifecycle.onStart(lbRequest);});//可以看到在这里会调用choose方法自动获取对应的服务实例信息ServiceInstance serviceInstance = this.choose(serviceId, lbRequest);if (serviceInstance == null) {supportedLifecycleProcessors.forEach((lifecycle) -> {lifecycle.onComplete(new CompletionContext(Status.DISCARD, lbRequest, new EmptyResponse()));});//没有发现任何此服务的实例就抛异常(之前的测试中可能已经遇到了)throw new IllegalStateException("No instances available for " + serviceId);} else {//成功获取到对应服务的实例,这时就可以发起HTTP请求获取信息了return this.execute(serviceId, serviceInstance, lbRequest);}
}
所以,实际上在进行负载均衡的时候,会向Eureka发起请求,选择一个可用的对应服务,然后会返回此服务的主机地址等信息:
自定义负载均衡策略
LoadBalancer默认提供了两种负载均衡策略:
- RandomLoadBalancer - 随机分配策略
- (默认) RoundRobinLoadBalancer - 轮询分配策略
现在我们希望修改默认的负载均衡策略,可以进行指定,比如我们现在希望用户服务采用随机分配策略,我们需要先创建随机分配策略的配置类(不用加@Configuration
):
public class LoadBalancerConfig {//将官方提供的 RandomLoadBalancer 注册为Bean@Beanpublic ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory){String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}
接着我们需要为对应的服务指定负载均衡策略,直接使用注解即可:
@Configuration
@LoadBalancerClient(value = "userservice", //指定为 userservice 服务,只要是调用此服务都会使用我们指定的策略configuration = LoadBalancerConfig.class) //指定我们刚刚定义好的配置类
public class BeanConfig {@Bean@LoadBalancedRestTemplate template(){return new RestTemplate();}
}
接着我们在BlockingLoadBalancerClient
中添加断点,观察是否采用我们指定的策略进行请求:
发现访问userservice服务的策略已经更改为我们指定的策略了。
LoadBalancer 负载均衡相关推荐
- Spring Cloud LoadBalancer(负载均衡)
简介 了解过Spring Cloud,就知道,之前Spring Cloud中默认的负载均衡组件为ribbon,ribbon是Netflix开源的组件,但是目前已经停止更新了.所以Spring官方推出了 ...
- 负载均衡之LoadBalancer
1.LoadBalancer负载均衡基本实现 2.基本使用 添加LoadBalanced注解 在调用的链接中,将IP和端口替换成应用名称 3.增加 spring-cloud-product-servi ...
- SpringCloud之 LoadBalancer和Feign负载均衡
文章目录 LoadBalancer 负载均衡 一.@LoadBalanced 负载均衡
- .net core grpc consul 实现服务注册 服务发现 负载均衡(二)
在上一篇 .net core grpc 实现通信(一) 中,我们实现的grpc通信在.net core中的可行性,但要在微服务中真正使用,还缺少 服务注册,服务发现及负载均衡等,本篇我们将在 .net ...
- 企业级负载均衡集群——lvs的DR模式(直接路由模式)详细说明
1.DR模式的原理 其实就是在一台主机上面搭建lvs服务器,设置lvs的工作模式是DR模式,lvs仅仅是一个调度器,它会把客户端的请求转发给后备服务器 DR模式直接由后备服务器把数据返回给客户端,不需 ...
- 如何在CentOS 7上使用HAproxy Loadbalancer设置Percona XtraDB集群(负载均衡)
翻译&转载来源:https://linoxide.com/cluster/setup-percona-cluster-haproxy-centos-7/ 如何在CentOS 7上使用HApro ...
- 客户端负载均衡 Loadbalancer
acos 通过服务发现拿到了所有的可用服务节点列表,但服务请求只能发给一个节点,你知道服务调用是根据什么规则选择目标节点的吗? 负载均衡的作用:了解负载均衡的两大门派,它们分别是网关层负载均衡和客户端 ...
- 【官方文档】Nginx负载均衡学习笔记(二)负载均衡基本概念介绍
简介 负载均衡(Server Load Balancer)是将访问流量根据转发策略分发到后端多台 ECS 的流量分发控制服务.负载均衡可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应 ...
- 使用Apache对Tomcat进行负载均衡
翻译:疯狂的技术宅 原文标题:Load balancing tomcat with Apache 原文链接:http://programmergate.com/loa... 本文首发微信公众号:充实的 ...
- saltstack实现haproxy+keepalived负载均衡+高可用(二)
一键部署haproxy+keepalived实现负载均衡+高可用 实验环境: !!!! 特别注意: www.westos.org为test1的minion名字 test1: 172.25.1.1 ...
最新文章
- HDFS配置Kerberos认证
- 经典网页设计:10个响应式设计的国外购物网站
- antlr4 idea插件_正则都搞不定、我还有Antlr4解析器
- Chrome 调试技巧
- python 函数可以作为容器对象的元素_11.Python初窥门径(函数名,可迭代对象,迭代器)...
- 用c语言编程计算10,计算方法c语言编程.doc
- vue 加载数据 影响seu_VUE常见面试题
- split和explode有什么区别?
- python滚动条翻页爬取数据_[Selenium2+python2.7][Scrap]爬虫和selenium方式下拉滚动条获取简书作者目录并且生成Markdown格式目录...
- Exponentially Weighted Averages
- Linux中查看bz2压缩文件大小,Linux bz2文件解压与压缩之bzip2命令
- 在Cadence中使用ADE进行蒙特卡洛仿真
- 微信公众号添加html,微信公众号添加页面模板怎么开通?
- 阿里云云计算ACP学习(八)---网络与VPC
- C# *未能找到类型“ * ”,请确保已引用包含此类型的程序集。如果此类型为开发项目的一部分,请确保已使用针对当前平台或任意 CPU 的设置成功生成该项目
- 3分频器 verilog解析
- C#查询自己的公网IP接口(有服务器)
- java : word,excel,img,ppt各种文档转换pdf格式以流方式
- xp透明膜p系列_一种XPP型超厚医用吸塑包装膜的制作方法
- 在JS中利用for...in循环遍历对象
热门文章
- 关于百度SDK的返回错误-PERMISSION UNFINISHED
- 微信定时发消息Python代码,简单好玩
- 四大免费magento支付接口扩展
- Python(28)---模块和包的基本概念
- 用c语言编写6位计算器,用c语言编写易简计算器.doc
- ctf piapiapia(反序列化逃逸)解题记录
- 数据结构与算法 知识点总结(中)---线性表,堆栈,队列
- 山东省农商行计算机真题,2018山东农商行招聘考试题库:计算机试题三
- 【论文阅读】Image Super-Resolution Using Deep Convolutional Networks
- 机器学习超详细实践攻略(9):手把手带你使用决策树算法与调参