多机部署,负载均衡
目录
负载均衡介绍
问题引出
什么是负载均衡
负载均衡的一些实现
服务端负载均衡
客户端负载均衡
Spring Cloud LoadBalancer
使用
负载均衡策略
自定义负载均衡策略
LoadBalancer 原理
服务部署
服务构建打包
完!
负载均衡介绍
问题引出
上篇文章中,实现远程调用的代码如下:
根据应用名称获取到了服务实例列表,从列表中选择了一个服务实例。
但如果一个服务对应多个实例呢?流量在这些实例中是如何分配?
现象观察:
在 Services 中先启动三个服务
然后再多启动两个 product-service 实例
此时观察 eureka,可用看到 product-service 下有三个实例。
此时访问:127.0.0.1:8080/order/1
通过日志发现,发出了多次访问,但都到了同一台机器上。
我们希望的是,启动多个实例之后,请求可用被分担到其他机器上。
解决:
对 order-service 中的 service 再进行修改:
重启 order-service,通过日志可以观察,请求被均衡的分配在了不同的实例上,这就是负载均衡。
什么是负载均衡
负载均衡(Load Balance),是高并发,高可用系统必不可少的关键组件。
当服务流浪增大时候,会采用增加机器的方式进行扩容。负载均衡就是使用多个机器或者其他资源中,按照一定的规则合理分配负载。
负载均衡的一些实现
上面的案例中,我们简单对实例进行了轮询。在真实的开发环境中,会更加复杂。比如根据机器的配置进行负载分配...
服务多机部署的时候,开发人员都需要考虑负载均衡的实现,所以也出现了一些负载均衡器,来帮助我们实现负载均衡。
负载均衡器分为:服务端负载均衡和客户端负载均衡。
服务端负载均衡
在服务端进行负载均衡的算法分配。
比较有名的是 Nginx,请求先到达 Nginx 负载均衡器,然后通过负载均衡算法,在多个服务器之间选择一个进行访问。
客户端负载均衡
在客户端进行负载均衡的算法。
把负载均衡的功能,以库的方式集成到客户端,而不是由一台指定的负载均衡设备集中提供。
比如 Spring Cloud 的 Ribbon,请求发送到客户端,客户端从注册中心获取服务列表,在发送请求前,通过负载均衡算法选择一个服务器,然后进行访问。
Ribbon 是早期 Spring Cloud 的默认实现,由于不维护了,所以最新版本的 Spring Cloud 负载均衡集成的是 Spring Cloud LoadBalancer
客户端和服务端这两种负载均衡器,最大的区别在于服务清单所存储的位置。
Spring Cloud LoadBalancer
使用
1. 给 RestTemplate 这个 Bean 添加 @LoadBalanced 注解
2. 修改 IP 端口号为服务名称
这时候观察日志,就会发现请求已经被分配到 3 个实例上了。
负载均衡策略
负载均衡是一种思想。Spring Cloud Load Balancer 仅支持两种负载均衡策略:轮询策略和随机策略。
1. 轮询:就是指服务器轮流处理用户的请求,这是一种实现最简单,也是最常用的策略。
2. 随机:随机选择一个后端服务器来处理新的请求。
自定义负载均衡策略
Spring Cloud LoadBalancer 默认负载均衡策略是轮询策略,实现是 RoundBobinLoadBalancer。
如果要实现随机的负载均衡策略:
根据官网地址:Spring Cloud LoadBalancer :: Spring Cloud Commons
在我们的项目中,实现一个 CustomLoadBalancerConfiguration 类。
我们使用的 RestTemplate 实现的远程调用,则在上面加上 @LoadBalancerClient 注解
看一下 @LoadBalancerClient 注解的属性:name / value 和 configuration
在 RestTemplate 配置
重新部署,实现了随机负载分配~
LoadBalancer 原理
LoadBalancer 的实现,主要是 LoadBalancerInterceptor,这个类会对 RestTemplate 的请求进行拦截,然后从 Eureka 根据服务 id 获取服务列表,然后利用均衡算法,得到真实的服务地址信息,替换服务 id。
源码实现:
在 intercept 方法中,拦截了用户的 HttpRequest
1. request.getURI() 从请求中获取了 URI
2. orginalUri.getHost() 从 uri 中获取到了路径的主机名,也就是服务 id,product-service
3. loadBalancer.execute 根据服务 id 进行负载均衡,并请求处理。
点进行进行追踪:
在 choose 方法中,根据 serviceId 和负载均衡策略,选择处理的服务。
在 choose 中,先获取负载均衡器,然后根据算法,选择一个服务实例
可以再点进去这个 choose 中进行观察
这个接口,就由轮询和随机负载均衡的实现~
服务部署
接下来我们将服务部署到 Linux 系统上
在 Linux 系统中,同样建立数据库。
服务构建打包
采用 Maven 进行打包,需要对三个服务分别进行打包
在子项目中 order-service 和 product-service 中的 pom 文件中进行如下配置
再对 application.yml 进行复制配置:
在 prod 生产环境中,对数据库的密码进行修改。
然后在 application.yml 文件中,让 Maven 仓库进行自动选择:
之后在 Maven 仓库中,选择 prod 环境进行打包
将 jar 包放到云服务器中,直接拖动文件到 xshell 窗口即可。
(第一次上传,需要安装 lrzsz : apt install lrzsz)
启动服务:
在云服务器控制台中,在防火墙设置中,将对应的端口号进行开放。
测试:
访问公网 ip:8080/order/1
远程调用实现成功。