OpenResty 动态负载均衡

OpenResty 动态负载均衡,第1张

在之前提到的OpenResty/Nginx的负载均衡当中,当服务器启动之后,upstream中的上游服务器就是固定死的了,做不到动态的变更。这里面说到的变更,其实更多指的是增加机器。因为当上游服务器不可用时,upstream会自动将服务器摘除,但是当新增服务器时,upstream就做不到了。传统的负载均衡办法,就是能是修改配置,然后重启服务。下面介绍一下动态负载均衡的方式,一种是通过动态重启服务;另外一种是通过代码的方式动态拉取服务器列表。

Consul是一个分布式服务注册与发现系统。这里面使用Consul来管理上游服务器,当服务器启动时将其注册到注册中心去,当服务关闭时从注册中心列表中剔除。这里面需要注意一点的是:当上游服务器关闭时,Consul本身不会自动从列表中剔除,而是需要在服务器关闭前主动向Consul发起删除服务。

Consul有以下特性:

通过Consul可以获取到upstream中的上游服务器列表,下面要做的事情就是生成upstream中的模板了。这里就需要用到Consul-templete,它可以使用HTTP长轮询实现变更触发和配置更改。从而可以根据Consul服务器列表动态生成配置文件,然后去重新启动OpenResty/Nginx即可。

Consul+Consul-templete 就如上面所说的,是一种监听服务器列表变更,然后动态生成upstream模板,重启服务器。

Consul-Server

笔者使用的是MAC,下面所进行的操作都是基于MAC系统的。首先需要安装Consul如下:

安装完成之后,可以通过如下命令启动Consul服务:

启动完成之后,可以通过如下地址:localhost:8500/ui。访问Consul的Web界面:

可以使用HTTP的方式向Consul注册一个服务:

Consul-template

Consul-template的作用是生成upstream配置模板,安装命令如下:

然后在nginx.conf同级目录下创建moguhu_server.ctmpl

重启OpenResty脚本如下:reboot.sh

然后nginx.conf配置如下:

上游服务器

上游服务器upstream中使用的是Spring Boot实现的,其核心代码如下所示:

笔者在实验时,Consul版本的问题,造成在JVM停止时,没有执行删除服务的操作。因此附上下面的pom依赖

测试验证

1、启动Consul

2、启动Consul-template

3、启动2台upstream服务器

然后你会发现在nginx.conf的同级目录下生成了moguhu_server.conf文件,内容如下:

当手动停掉一台服务器时,配置又会变更为如下:

此时reboot.sh脚本会自动触发执行,如下所示:

上面的方式实现动态负载均衡在配置较多的时候会有一些问题,比如配置较多时,OpenResty重启的速度就会变慢。所以通过Lua脚本的方式可以规避掉重启这一步骤。

使用Lua实现时,与上面的组件相比Consul-templete就不需要了。通过Consul的 http://127.0.0.1:8500/v1/catalog/service/moguhu_server 接口就可以获取到服务的列表,如下所示:

这一方式当中主要就是OpenResty里面的相关配置。

OpenResty 配置

upstreams.lua

nginx.conf

上面通过balancer_by_lua_block去动态的设置了,upstream的服务器列表。然后启动OpenResty就可以了。

参考:《亿级流量网站架构核心技术》

Spring Cloud Ribbon 是 Netflix Ribbon 实现的一套客户端 负载均衡工具

Ribbon 是 Netflix 发布的开源项目,主要功能是提供 客户端的复杂均衡算法和服务调用。

Ribbon 客户端组件提供一系列完善的配置项如超时、重试等。

Ribbon 会自动的帮助你基于某种规则(如简单轮询,随机链接等)去链接这些机器。

    Nginx 是服务器负载均衡,客户端所有请求都会交给nginx, 然后 nginx 实现转发请求。即负载均衡是由服务端实现的。

    Ribbon 本地负载均衡,在调用微服务接口的时候,会在注册中心上获取注册信息服务列表后缓存到JVM 本地,从而在本地实现RPC远程 服务调用技术。

第一步先选择 Server , 它优先选择在同一个区域呢负载较少的Server

第二步在根据用户执行的策略,在从server 取到的服务注册列表中选择一个地址。

其中 Ribbon 提供了多种策略:比如轮询、随机和根据响应时间加权。

1、集中式

即在服务的消费方和提供方之间使用独立的LB 设施(可以是硬件,如F5, 也可以是软件如 Nginx ), 由该设置负责把访问请求通过某种策略转发至服务的提供方

2、进程内 LB

将 LB 逻辑集成到消费方,消费方从服务注册中心获取有哪些地址可用,然后自己再从这些地址中选择一个适合的服务器。

@LoadBalance + RestTemplate

@LoadBalanced是标记注释,@RibbonClient用于配置目的。

负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端负载均衡器,而今天的主角Ribbon就是属于后者--客户端负载均衡器。

服务端负载均衡器的问题是,它提供了更强的流量控制权,但无法满足一同的消费者希望使用不同负载均衡策略的需求,而使用不同负载均衡策略的场景确实是存在的,所以客户端负载均衡就提供了这种灵活性。 然而客户端负载均衡也有其缺点,如果配置不当,可能会导致服务提供者出现热点,或者压根就拿不到任何服务的情况。及了解一下Ribbon的7种内置负载均衡策略的具体规则。

Ribbon是Spring Cloud技术栈中非常重要的基础框架,它为Spring Cloud提供了负载均衡的能力,比如Fegin和OpenFegin都是基于Ribbon实现的,就连Nacos中的负载均衡也使用了Ribbon框架。

Ribbon框架的强大之处在于,它不仅内置了7种负载均衡策略,同时还支持用户自定义负载均衡策略,所以其开放性和便利性也是它得以流行的主要原因。

服务端负载均衡和客户端负载均衡的区别如下所示:

客户端负载均衡器的实现原理是通过注册中心,如Nacos,将可用的服务列表拉取到本地(客户端),在通过客服端负载均衡器(设置的负载均衡策略)获取到某个服务器的具体IP和端口,然后在通过HTTP框架请求服务并得到结果,其执行流程如下所示:

以Nacos中Ribbon负载均衡设置为例,在配置文件 application.yml 中设置如下配置即可:

因为Nacos中已经内置了Ribbon,所以在实现项目开发中无需再引用Ribbon依赖了,这一点我们在Nacos的依赖树中就可以看到,如下所示:

轮询策略:RoundRobinRule,按照一定的顺序依次调用服务实例。比如一共有 3 个服务,第一次调用服务 1,第二次调用服务 2,第三次调用服务3,依次类推。此策略的配置设置如下:

权重策略:WeightedResponseTimeRule,根据每个服务提供者的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性也就越低。它的实现原理是,刚开始使用轮询策略并开启一个计时器,每一段时间收集一次所有服务提供者的平均响应时间,然后再给每个服务提供者附上一个权重,权重越高被选中的概率也越大。此策略的配置设置如下:

随机策略:RandomRule,从服务提供者的列表中随机选择一个服务实例。此策略的配置设置如下:

最小连接数策略:BestAvailableRule,也叫最小并发数策略,它是遍历服务提供者列表,选取连接数最小的一个服务实例。如果有相同的最小连接数,那么会调用轮询策略进行选取。此策略的配置设置如下:

重试策略:RetryRule,按照轮询策略来获取服务,如果获取的服务实例为null或已经失效,则在指定的时间之内不断地进行重试来获取服务。如果超过指定时间依然没获取到服务实例则返回null。此策略的配置设置如下:

可用敏感性策略:AvailabilityFilteringRule,先过滤掉非健康的服务实例,然后在选择连接数较小的服务实例。此策略的配置设置如下:

区域敏感策略:ZoneAvoidanceRule,根据服务所在区域(zone)的性能和服务的可用性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似。此策略的配置设置如下:

Ribbon 为客户端负载均衡器,相比于服务端负载均衡器的统一负载均衡策略来说,它提供了更多的灵活性。Ribbon 内置了 7 种负载均衡策略:轮询策略、权重策略、随机策略、最小连接数策略、重试策略、可用性敏感策略、区域性敏感策略,并且用户可以通过继承 RoundRibbonRule 来实现自定义负载均衡策略。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/800559.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-08-28
下一篇2023-08-28

发表评论

登录后才能评论

评论列表(0条)

    保存