当前位置: 首页 > news >正文

nginx 简单实践:负载均衡【nginx 实践系列之四】

〇、前言

本文为 nginx 简单实践系列文章之三,主要简单实践了负载均衡,仅供参考。

注意:可以使用测试域名,但前提是要修改 hosts 文件

路径和重启:Linux(/etc/hosts)(重启命令:/etc/init.d/network restart);Windows(C:\Windows\System32\drivers\etc\hosts)。

例如:192.168.1.1 www.testczzj.com

一、关于负载均衡

1.1 简介

负载均衡(Load Balance,简称 LB)是高并发、高可用系统必不可少的关键组件,目标是尽力将网络流量平均分发到多个服务器上,以提高系统整体的响应速度和可用性。

主要的作用:

  • 高并发:负载均衡通过算法调整负载,尽力均匀的分配应用集群中各节点的工作量,以此提高应用集群的并发处理能力(吞吐量)。

  • 伸缩性:添加或减少服务器数量,然后由负载均衡进行分发控制。这使得应用集群具备伸缩性。

  • 高可用:负载均衡器可以监控候选服务器,当服务器不可用时,自动跳过,将请求分发给可用的服务器。这使得应用集群具备高可用的特性。

  • 安全防护:有些负载均衡软件或硬件提供了安全性功能,如:黑白名单处理、防火墙,防 DDos 攻击等。

1.2 载体维度分类:硬件

硬件负载均衡,一般是在定制处理器上运行的,独立负载均衡服务器价格昂贵

硬件负载均衡的主流产品有:F5 和 A10。F5 拥有更广泛的附加功能和服务,而 A10 则在某些特定领域如 IPv6 转换或 SSL 检查方面表现出色。

优点:

  • 功能强大:支持全局负载均衡并提供较全面的、复杂的负载均衡算法。

  • 性能强悍:硬件负载均衡由于是在专用处理器上运行,因此吞吐量大,可支持单机百万以上的并发。

  • 安全性高:往往具备防火墙,防 DDos 攻击等安全功能。

缺点:

  • 成本昂贵:购买和维护硬件负载均衡的成本都很高。

  • 扩展性差:当访问量突增时,超过限度不能动态扩容。

1.3 载体维度分类:软件

软件负载均衡是指,使用软件工具或解决方案来分配网络流量或计算任务到多个服务器,以实现资源的有效利用、提高系统性能和增强服务的可用性。

与硬件负载均衡器相比,软件负载均衡更加灵活、成本效益更高,并且可以轻松部署在标准的服务器硬件上

软件负载均衡通常位于客户端和服务器之间,它接收来自客户端的请求,并根据预先设定的算法决定将这些请求转发到哪一个后端服务器。通过这种方式,它可以确保工作负载均匀分布,避免任何单一服务器过载。

优点:

  • 扩展性好:适应动态变化,可以通过添加软件负载均衡实例,动态扩展到超出初始容量的能力。

  • 成本低廉:软件负载均衡可以在任何标准物理设备上运行,降低了购买和运维的成本。

缺点:

  • 性能略差:相比于硬件负载均衡,软件负载均衡的性能要略低一些。

1.4 网络通信分类:七层负载均衡

1.4.1 DNS 负载均衡

DNS(Domain Name System 域名解析系统)负载均衡一般用于互联网公司,复杂的业务系统不适合使用。大型网站一般使用 DNS 负载均衡作为第一级负载均衡手段,然后在内部使用其它方式做第二级负载均衡。

什么是 DNS?它是 OSI 第七层网络协议。DNS 被设计为一个树形结构的分布式应用,自上而下依次为:权威服务器,顶级服务器,根域名服务器,递归服务器,本地DNS服务器。

下边简单列举下:

DNS 负载均衡的工作原理就是:基于 DNS 查询缓存,按照负载情况返回不同服务器的 IP 地址。

如下图,针对服务集群中的两个服务地址 127.0.0.1、127.0.0.2,在 DNS 服务器中都配置为指向域名 www.xxx.com,当用户通过域名访问时,请求到 DNS 服务器,然后随机返回一个实际请求的服务器 IP 地址。

优点:

简易部署与管理:无需改变应用程序的代码,仅通过配置DNS即可实现负载分发,简化了服务器集群的管理。地理分布优化:支持基于地理位置的流量分配,能够将用户请求定向到距离最近的数据中心或服务器,从而减少延迟,提高访问速度。扩展性强:可以轻松地向服务器池中添加新的服务器,以应对增加的流量需求,提高了系统的可伸缩性。成本效益高:通过更有效的资源利用减少了硬件投资和运营成本。

缺点:

缓存问题:由于DNS解析结果会被客户端及中间DNS服务器缓存,当某个服务器出现故障时,已缓存该服务器IP地址的用户仍然可能被导向至故障服务器,直到缓存过期。这可能导致服务中断或性能下降。负载平衡精度有限:DNS负载均衡通常基于简单的算法(如轮询)进行分配,无法实时感知各服务器的实际负载情况,导致负载分配不够精准。安全性考虑:尽管DNSSEC等技术增强了DNS的安全性,但DNS本身仍可能存在被攻击的风险,例如DDoS攻击,可能会对整个系统造成影响。不支持会话持久化:如果应用需要保持用户的会话状态,单纯的DNS负载均衡无法保证用户在多次请求间总是被导向到同一台服务器,除非结合其他机制来实现。

虽然 DNS 负载均衡提供了一种简单且有效的方法来分散网络流量,但它也存在一定的局限性。因此,在实际应用中,常常需要结合使用其他技术和策略,如健康检查、自动故障转移以及会话保持机制等,以克服其固有的不足。

1.4.2 HTTP 负载均衡

HTTP 负载均衡是基于 HTTP 重定向实现的。HTTP 负载均衡属于七层负载均衡。

HTTP 重定向原理是:根据用户的 HTTP 请求计算出一个真实的服务器地址,将该服务器地址写入 HTTP 重定向响应中,返回给浏览器,由浏览器重新进行访问。

优点:

高可用性和可靠性:即使某台服务器发生故障,负载均衡器也能自动将流量分配到其他健康的服务器上,从而保证服务的连续性。扩展性:可以轻松添加更多的服务器到池中以应对增加的负载,提高了系统的可伸缩性。性能提升:通过智能地选择最佳的服务器来处理每个请求,可以减少响应时间和提高用户体验。安全性增强:负载均衡器可以充当额外的安全层,提供诸如 SSL 终止、DDoS 防护等功能,保护后端服务器免受攻击。会话持久化支持:一些高级负载均衡器支持会话持久化功能,确保用户在整个会话过程中总是被导向到同一台服务器。

缺点:

性能较差:每次访问需要两次请求服务器,增加了访问的延迟。降低搜索排名:使用重定向后,搜索引擎会视为 SEO 作弊。复杂性和成本:实现和维护 HTTP 负载均衡需要一定的技术知识和投入,包括硬件成本、软件许可证费用以及维护成本。单点故障风险:如果负载均衡器本身出现故障,则可能导致整个系统不可用。虽然可以通过设置主备负载均衡器来缓解这一问题,但这增加了架构的复杂度。潜在的瓶颈:在高并发情况下,如果负载均衡器本身的处理能力不足,可能会成为系统的瓶颈。

由于其缺点比较明显,所以这种负载均衡策略实际应用较少。

1.4.3 反向代理

反向代理(Reverse Proxy)方式是指以 代理服务器 来接受网络请求,然后 将请求转发给内网中的服务器,并将从内网中的服务器上得到的结果返回给网络请求的客户端。反向代理负载均衡属于七层负载均衡。

反向代理服务的主流产品:Nginx、Apache

如下图,看下 Nginx 如何实现负载均衡:

首先,在代理服务器上设定好负载均衡规则。

然后,当收到客户端请求,反向代理服务器拦截指定的域名或 IP 请求,根据负载均衡算法,将请求分发到候选服务器上。

其次,如果某台候选服务器宕机,反向代理服务器会有容错处理,比如分发请求失败 3 次以上,将请求分发到其他候选服务器上。

优点:

多种负载均衡算法:支持多种负载均衡算法,以应对不同的场景需求。可以监控服务器:基于 HTTP 协议,可以监控转发服务器的状态,如:系统负载、响应时间、是否可用、连接数、流量等,从而根据这些数据调整负载均衡的策略。

缺点:

额外的转发开销:反向代理的转发操作本身是有性能开销的,可能会包括创建连接,等待连接响应,分析响应结果等操作。增加系统复杂度:反向代理常用于做分布式应用的水平扩展,但反向代理服务存在以下问题,为了解决以下问题会给系统整体增加额外的复杂度和运维成本。

反向代理服务如果自身宕机,就无法访问站点,所以需要有高可用方案,常见的方案有:主备模式(一主一备)、双主模式(互为主备)。

反向代理服务自身也存在性能瓶颈,随着需要转发的请求量不断攀升,需要有可扩展方案

1.5 网络通信分类:四层负载均衡

1.5.1 IP 负载均衡

IP 负载均衡是在网络层通过修改请求目的地址进行负载均衡。

如上图,大致流程为:

1. 客户端请求 192.168.137.10,由负载均衡服务器接收到报文。

2. 负载均衡服务器根据算法选出一个服务节点 192.168.0.1,然后将报文请求地址改为该节点的 IP。

3. 真实服务节点收到请求报文,处理后,返回响应数据到负载均衡服务器。

4. 负载均衡服务器将响应数据的源地址改负载均衡服务器地址,返回给客户端。

IP 负载均衡在内核进程完成数据分发,较反向代理负载均衡有更好的从处理性能。但是,由于所有请求响应都要经过负载均衡服务器,集群的吞吐量受制于负载均衡服务器的带宽

1.5.2 数据链路层通过修改 mac 地址来实现负载均衡

数据链路层负载均衡是指,在通信协议的数据链路层修改 mac 地址进行负载均衡。

在 Linux 平台上最好的链路层负载均衡开源产品是 LVS (Linux Virtual Server)。

LVS 是基于 Linux 内核中 netfilter 框架实现的负载均衡系统。netfilter 是内核态的 Linux 防火墙机制,可以在数据包流经过程中,根据规则设置若干个关卡(hook 函数)来执行相关的操作。

LVS 的工作流程大致如下:

1. 客户端请求:当客户端发起一个请求到目标服务时,首先会到达 LVS 配置的虚拟 IP 地址(VIP),这个 VIP 对外代表了一个或多个实际提供服务的服务器集群。

2. 流量分发的四种模式: 

1)IPVS 模块:LVS 的核心是运行在 Linux 内核中的 IPVS(IP Virtual Server)模块,它负责根据预设的负载均衡算法(如轮询、最少连接数等)将收到的请求分发给后端的真实服务器(Real Server, RS)。

 2)直接路由模式(DR:Direct Routing):在此模式下,LVS 简单地重写数据包的目标 MAC 地址为选定真实服务器的 MAC 地址,并将数据包发送回交换机,由交换机转发给真实服务器。这种方式不需要修改数据包的 IP 头部信息,因此效率很高。

 3)NAT 模式(Network Address Translation):在这种模式下,LVS 不仅改变目标 MAC 地址,还会修改目标 IP 地址为目标服务器的实际 IP 地址,并且处理来自真实服务器的响应,将其源 IP 地址改为 VIP 后再返回给客户端。此方法适用于真实服务器位于私有网络的情况。 

4)隧道模式(Tunnel:Tunneling):通过将原始请求封装在 IP 隧道中发送给真实服务器,允许真实服务器位于不同的物理位置,只要它们能够与 LVS 通信即可。

3. 真实服务器处理请求:被选中的真实服务器接收到请求后进行处理,并直接将响应发送回客户端(在直接路由和隧道模式下),或者通过 LVS 返回给客户端(在 NAT 模式下)。

4. 健康检查:LVS通常结合外部工具(如keepalived)来进行真实服务器的健康检查。如果某个真实服务器不可用,LVS将停止向其分配新的请求,直到它恢复正常。

1.6 负载均衡算法简介

负载均衡器的实现可以分为两个部分:首先通过负载均衡算法在候选服务器列表选出一个服务器;然后,将请求数据发送到该服务器上。

负载均衡算法是负载均衡服务核心中的核心。

负载均衡产品多种多样,但是各种负载均衡算法原理是共性的。负载均衡算法有很多种,分别适用于不同的应用场景,常用的有:轮询、随机、最小活跃数、源地址哈希、一致性哈希等等,下文将逐个简单介绍。

  • 随机算法(Random)

随机算法将请求随机分发到候选服务器。更适合服务器硬件相同的场景。当调用量较小的时候,可能负载并不均匀,调用量越大,负载越均衡。

  • 加权随机算法(Weighted Random)

加权随机算法在随机算法的基础上,按照概率调整权重,进行负载分配。

  • 轮询算法(Round Robin)

轮询算法的策略是:将请求依次分发到候选服务器。

该算法适合场景:各服务器处理能力相近,且每个事务工作量差异不大。如果存在较大差异,那么处理较慢的服务器就可能会积压请求,最终无法承担过大的负载。

  • 加权轮询算法(Weighted Round Robbin)

加权轮询算法在轮询算法的基础上,增加了权重属性来调节转发服务器的请求数目。

性能高、处理速度快的节点应该设置更高的权重,使得分发时优先将请求分发到权重较高的节点上。

  • 最少连接数(Least Connections)

最少连接数算法将请求分发到连接数/请求数最少的候选服务器(目前处理请求最少的服务器)。

它是根据候选服务器当前的请求连接数,动态分配。

适用于对系统负载较为敏感或请求连接时长相差较大的场景

由于每个请求的连接时长不一样,如果采用简单的轮循或随机算法,都可能出现某些服务器当前连接数过大,而另一些服务器的连接过小的情况,这就造成了负载并非真正均衡。虽然,轮询或随机算法都可以通过加权重属性的方式进行负载调整,但加权方式难以应对动态变化

  • 加权最少连接数(Weighted Least Connections)

结合了加权轮询和最少连接数的优点,在选择服务器时既考虑了服务器的当前连接数也考虑了其权重,使得更强大的服务器可以处理更多的请求

  • 源 IP 地址哈希(Source IP Hash)

根据客户端 IP 地址计算哈希值,并根据哈希结果选择服务器。

这种方式可以确保来自同一客户端的请求总是被发送到相同的服务器上,有助于保持会话状态的一致性,用来实现会话粘滞(Sticky Session)。

  • 一致性哈希(Consistent Hash)

一致性哈希算法的目标是:相同的请求尽可能落到同一个服务器上。

一致性哈希可以很好的解决稳定性问题,可以将所有的存储节点排列在首尾相接的 Hash 环上,每个 key 在计算 Hash 后会顺时针找到临接的存储节点存放。而当有节点加入或退出时,仅影响该节点在 Hash 环上顺时针相邻的后续节点。

‘相同的请求’是指:一般在使用一致性哈希时,需要指定一个 key 用于 hash 计算,可能是:用户 ID、请求方 IP、请求服务名称、参数列表构成的串等等。

‘尽可能’是指:服务器可能发生上下线,少数服务器的变化不应该影响大多数的请求。当某台候选服务器宕机时,原本发往该服务器的请求,会基于虚拟节点,平摊到其它候选服务器,不会引起剧烈变动。

优点:加入和删除节点只影响哈希环中顺时针方向的相邻的节点,对其他节点无影响。

缺点:加减节点会造成哈希环中部分数据无法命中。当使用少量节点时,节点变化将大范围影响哈希环中数据映射,不适合少量数据节点的分布式方案。普通的一致性哈希分区在增减节点时需要增加一倍或减去一半节点才能保证数据和负载的均衡。

二、Nginx 的负载均衡简单测试

2.1 轮询【默认方式】

轮询算法是默认的一种方式。

当 nginx 接收到请求后,逐一分配到所配置的服务列表进行访问并返回。

当某个服务异常时,自动跳过,并不会导致请求失败。

实例配置如下:

# 反向代理配置
upstream server_czzj {server www.testczzj.com:5001;server www.testczzj.com:5021;server www.testczzj.com:5031;
}server {listen 8888;server_name www.testczzj.com;access_log  /var/log/nginx/access.log;error_log  /var/log/nginx/error.log;location / {index index.html index.htm;proxy_pass http://server_czzj; # 指定反向代理服务器列表}
}

如下图,刷新同一地址,请求的服务不同:

2.2 weight【权重】

权重用于调整不同服务器之间请求分配比例。

它允许管理员根据每台服务器的实际处理能力和性能,来手动控制流量分配,从而优化资源利用和提高系统的整体效率。

通过合理设置权重,可以根据实际需求动态调整服务器之间的负载分布,不仅提高了系统的灵活性和可靠性,还能更好地应对突发流量和资源限制等问题。

配置示例:

# 反向代理配置
upstream server_czzj {server www.testczzj.com:5001 weight=1; # 默认为 1,可不配置server www.testczzj.com:5021 weight=3;server www.testczzj.com:5031 weight=6;
}

解释:例如示例中的权重总量为 10,那么如果 nginx 接到十个请求,那么三个服务就分别接到 1、3、6 个请求。但是首次请求进入那个服务是不固定的,权重为 6 的服务概率最大。

实际效果就类似于:(但是顺序是随机的)

# 反向代理配置
upstream server_czzj {server www.testczzj.com:5001;server www.testczzj.com:5021;server www.testczzj.com:5021;server www.testczzj.com:5021;server www.testczzj.com:5031;server www.testczzj.com:5031;server www.testczzj.com:5031;server www.testczzj.com:5031;server www.testczzj.com:5031;server www.testczzj.com:5031;
}

此策略比较适合服务器的硬件配置差别比较大的情况。

2.3 ip_hash【基于客户端 IP 来分配】

指定负载均衡器按照基于客户端 IP 的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,以保证 session 会话。这样每个访客都固定访问一个后端服务器,可以解决 session 不能跨服务器的问题。

Nginx 使用的 Jenkins hash 函数对输入数据(如 IP 地址)进行哈希计算,生成一个 32 位无符号整数作为哈希值。对于 IP 地址 127.0.0.1,经过 Jenkins hash 计算后,得到的哈希值为 879045407。

如果有三个服务且权重均为1,则通过哈希值对3取余,得到的 0、1、2 分别对应三个服务。

如果有多个权重不同的服务,则通过对权重总和的值取余,得到序号,对应到不同的服务上。

实例配置:

# 反向代理配置
upstream server_czzj {ip_hash; # 保证每个客户端访问同一个后端服务server www.testczzj.com:5001;server www.testczzj.com:5021;server www.testczzj.com:5031;
}

注意:在 nginx 版本 1.3.1 之前,不能在 ip_hash 中使用权重(weight)。

ip_hash 不能与 backup(配置备用服务)同时使用

此策略适合有状态服务,比如 session。

当有服务器需要剔除,必须手动进行停服操作

2.4 least_conn【最少连接】

把请求转发给连接数较少的后端服务。

轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn 这种方式就可以达到更好的负载均衡效果。

# 反向代理配置
upstream server_czzj {least_conn; # 把新的请求,转发到当前连接数最少的服务server www.testczzj.com:5001;server www.testczzj.com:5021;server www.testczzj.com:5031;
}

此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。

2.5 第三方策略:fair【按照最短响应时间分配请求】

此方式需要单独额外的配置,不能直接在 upstream 模块添加关键字 fair。

大概的思路就是,下载补充包,通过 ./configure 命令,将模块添加到已安装的 nginx,重启下服务就可以使用关键字 fair 了。

2.5.1 配置步骤和示例

1)先下载第三方包:https://github.com/gnosek/nginx-upstream-fair

文件很简单,如下图:

需要将此文件夹放到 linux 系统中,本示例复制到路径:/usr/local/nginx-upstream-fair-master。

2)进入 nginx 源文件所在的文件夹(即 nginx 安装包解压后的文件夹),本示例的是:/usr/local/nginx-1.20.0。

# 下载 nginx 包并解压
wget http://nginx.org/download/nginx-1.20.0.tar.gz
tar -zxf nginx-1.20.1.tar.gz && cd nginx-1.20.0/
# 其他一些可能用到的依赖包(按需安装)
yum -y install gcc gcc-c++ openssl openssl-devel zlib zlib-devel pcre pcre-devel make cmake gperftools perl-devel  gd-devel libxml2 libxml2-dev libxslt-devel  redhat-rpm-config.noarch

注意:如果源文件找不到了,需要重新下载一个相同版本安装包使用。

3)执行命令添加模块:

# 手动添加模块
./configure --add-module=/usr/local/nginx-upstream-fair-master
# 重新进行编译
[root@www nginx-1.20.0]# make
# 添加成功,注意 configure arguments 配置:
[root@www sbin]#  nginx -V
nginx version: nginx/1.20.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
configure arguments: --add-module=/usr/local/nginx-upstream-fair-master

4)然后先停止 nginx 服务,再将 nginx 进行复制:

# 先停止 nginx 服务
[root@www sbin]# ./nginx -s stop
# 复制 nginx
[root@www nginx-1.20.0]# cp -rp objs/nginx /usr/local/nginx/sbin/nginx
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? yes
[root@www nginx-1.20.0]#

最后,修改 nginx.conf 配置文件,开启服务测试一下。

配置示例:

# 反向代理配置
upstream server_czzj {fair; # 按照最短响应时间分配请求server www.testczzj.com:5001;server www.testczzj.com:5021;server www.testczzj.com:5031;
}

2.5.2 make 执行时报错:‘ngx_http_upstream_srv_conf_t’ has no member named ‘default_port’

ngx_http_upstream_srv_conf_t’没有名为‘default_port’的成员。

# 具体提示:
/usr/local/nginx-upstream-fair-master/ngx_http_upstream_fair_module.c: In function ‘ngx_http_upstream_init_fair_rr’:
/usr/local/nginx-upstream-fair-master/ngx_http_upstream_fair_module.c:543:28: error: ‘ngx_http_upstream_srv_conf_t’ has no member named ‘default_port’if (us->port == 0 && us->default_port == 0) {^
/usr/local/nginx-upstream-fair-master/ngx_http_upstream_fair_module.c:553:51: error: ‘ngx_http_upstream_srv_conf_t’ has no member named ‘default_port’u.port = (in_port_t) (us->port ? us->port : us->default_port);

# 解决,执行如下命令即可:
# Linux: 
sed -i 's/default_port/no_port/g' /usr/local/nginx-upstream-fair-master/ngx_http_upstream_fair_module.c
# macOs: 
sed -i '' 's/default_port/no_port/g' /file/ngx_http_upstream_fair_module.c

2.6 第三方策略:url_hash【按访问url的hash结果来分配请求】

此方式需要单独额外的配置,不能直接在 upstream 模块添加关键字 url_hash。

大概的思路就是,下载补充包,通过 ./configure 命令,将模块添加到已安装的 nginx,重启下服务就可以使用关键字 fair 了。

1)先下载第三方包:https://github.com/evanmiller/nginx_upstream_hash

文件很简单,如下图:

需要将此文件夹放到 linux 系统中,本示例复制到路径:/usr/local/nginx_upstream_hash-master。

2)进入 nginx 源文件所在的文件夹(即 nginx 安装包解压后的文件夹),本示例的是:/usr/local/nginx-1.20.0。

注意:如果源文件找不到了,需要重新下载一个相同版本安装包使用。

# 下载 nginx 包并解压
wget http://nginx.org/download/nginx-1.20.0.tar.gz
tar -zxf nginx-1.20.1.tar.gz && cd nginx-1.20.0/
# 其他一些可能用到的依赖包(按需安装)
yum -y install gcc gcc-c++ openssl openssl-devel zlib zlib-devel pcre pcre-devel make cmake gperftools perl-devel  gd-devel libxml2 libxml2-dev libxslt-devel  redhat-rpm-config.noarch

3)执行命令添加模块:

# 手动添加模块
[root@www nginx-1.20.0]# ./configure --add-module=/usr/local/nginx_upstream_hash-master
# 重新进行编译
[root@www nginx-1.20.0]# make
# 添加成功,查看配置,注意 configure arguments 配置:
[root@www nginx-1.20.0]# nginx -V
nginx version: nginx/1.20.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
configure arguments: --add-module=/usr/local/nginx_upstream_hash-master

4)然后先停止 nginx 服务,再将 nginx 进行复制:

# 先停止 nginx 服务
[root@www sbin]# ./nginx -s stop
# 复制 nginx
[root@www nginx-1.20.0]# cp -rp objs/nginx /usr/local/nginx/sbin/nginx
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? yes
[root@www nginx-1.20.0]#

最后,修改 nginx.conf 配置文件,开启服务测试一下。

配置示例:

# 反向代理配置
upstream server_czzj {hash $request_uri; # 相同的 url 定向到同一后端服务器# hash $remote_addr; # 也可根据客户端 IP 映射# hash $args; # 也可根据客户端携带的参数进行映射server www.testczzj.com:5001;server www.testczzj.com:5021;server www.testczzj.com:5031;
}

配置完成后就可以实现,相同的 url 请求到同一个服务。

另外,当某一个服务异常停止后,原来通过 hash 对应到此服务的请求,会自动对应到其他服务,并不会造成请求失败。

2.7 第三方策略:consistent_hash【采用一致性哈希算法结果来分配请求】

此方式需要单独额外的配置,不能直接在 upstream 模块添加关键字 consistent_hash。

大概的思路就是,下载补充包,通过 ./configure 命令,将模块添加到已安装的 nginx,重启下服务就可以使用关键字 consistent_hash了。

1)先下载第三方包:https://github.com/replay/ngx_http_consistent_hash

文件很简单,如下图:

需要将此文件夹放到 linux 系统中,本示例复制到路径:/usr/local/ngx_http_consistent_hash-master。

2)进入 nginx 源文件所在的文件夹(即 nginx 安装包解压后的文件夹),本示例的是:/usr/local/nginx-1.20.0。

注意:如果源文件找不到了,需要重新下载一个相同版本安装包使用。

# 下载 nginx 包并解压
wget http://nginx.org/download/nginx-1.20.0.tar.gz
tar -zxf nginx-1.20.1.tar.gz && cd nginx-1.20.0/
# 其他一些可能用到的依赖包(按需安装)
yum -y install gcc gcc-c++ openssl openssl-devel zlib zlib-devel pcre pcre-devel make cmake gperftools perl-devel  gd-devel libxml2 libxml2-dev libxslt-devel  redhat-rpm-config.noarch

3)执行命令添加模块:

# 手动添加模块
./configure --add-module=/usr/local/ngx_http_consistent_hash-master
# 重新进行编译
[root@www nginx-1.20.0]# make
# 添加成功,查看配置,注意 configure arguments 配置:
[root@www nginx-1.20.0]# nginx -V
nginx version: nginx/1.20.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
configure arguments: --add-module=/usr/local/ngx_http_consistent_hash-master

4)然后先停止 nginx 服务,再将 nginx 进行复制:

# 先停止 nginx 服务
[root@www sbin]# ./nginx -s stop
# 复制 nginx
[root@www nginx-1.20.0]# cp -rp objs/nginx /usr/local/nginx/sbin/nginx
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? yes
[root@www nginx-1.20.0]#

最后,修改 nginx.conf 配置文件,开启服务测试一下。

配置示例:

# 反向代理配置
upstream server_czzj {consistent_hash $request_uri; # 一致性哈希算法# consistent_hash $remote_addr; # 也可根据客户端 IP 映射# consistent_hash $args; # 也可根据客户端携带的参数进行映射server www.testczzj.com:5001;server www.testczzj.com:5021;server www.testczzj.com:5031;
}

文章转载自:橙子家

原文链接:nginx 简单实践:负载均衡【nginx 实践系列之四】 - 橙子家 - 博客园

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

相关文章:

nginx 简单实践:负载均衡【nginx 实践系列之四】

〇、前言 本文为 nginx 简单实践系列文章之三,主要简单实践了负载均衡,仅供参考。 注意:可以使用测试域名,但前提是要修改 hosts 文件 路径和重启:Linux(/etc/hosts)(重启命令&#…...

CentOS 7.9 安装 Python 3.10 详细步骤及常见问题解决

一、环境准备与依赖安装 更新系统与开发工具 sudo yum update -y sudo yum groupinstall "Development Tools" -y sudo yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel \ readline-devel tk-devel libffi-devel gdbm-devel db4-de…...

计算机网络-1-1计算机网络体系结构

第一章计算机网络体系结构 绪论 《计算机网络》学什么?——数据如何通过网络正确、可靠地从A传送到B 【考纲内容】 (一)计算机网络概述 计算机网络的概念、组成与功能;计算机网络的分类; 计算机网络的性能指标 (二)计算机网…...

集装箱箱号OCR识别技术,在铁路物流场站集装箱装卸机械数字化系统中的应用

集装箱装卸机械数字化是针对铁路物流场站的门式起重机、集装箱正面吊运起重机、重型叉车、堆高机等作业设备,在不影响原设备作业性能情况下,通过增加或集成集装箱箱号OCR识别或者车号识别装置、北斗定位装置、PLC采集装置等,利用多种通信协议…...

数仓工具—Hive语法之不同纬度聚合

不同纬度聚合 提到不同纬度聚合,大家想到的肯定是grouping sets,或者是cube和rollup 其实这些我们之前都讲过,可以看看之前的文章 数仓工具—Hive语法之cube和rollup 数仓工具—Hive语法之grouping sets 但是我们今天遇到的问题是,使用的工具不支持grouping sets,既然…...

GitHub在push推送到远程仓库的时候显示Logon failed登录失败

具体问题描述 git.exe push --progress "origin" master:master Logon failed, use ctrlc to cancel basic credential prompt. remote: Support for password authentication was removed on August 13, 2021. 这是因为Git 推送失败的原因是 GitHub 已经不支持密码认…...

【Dive Into Stable Diffusion v3.5】1:开源项目正式发布——深入探索SDv3.5模型全参/LoRA/RLHF训练

目录 1 引言2 项目简介3 快速上手3.1 下载代码3.2 环境配置3.3 项目结构3.4 下载模型与数据集3.5 运行指令3.6 核心参数说明3.6.1 通用参数3.6.2 优化器/学习率3.6.3 数据相关 4 结语 1 引言 在人工智能和机器学习领域,生成模型的应用越来越广泛。Stable Diffusion…...

2025-03-19 Unity 网络基础2——网络通信基础

文章目录 1 数据通信模型1.1 C/S 模型1.2 B/S 模型1.3 P2P 模型1.4 小结 2 网络协议2.1 OSI 模型2.1.1 下层2.1.2 上层 2.2 TCP/IP 协议2.2.1 TCP 协议2.2.2 UDP 协议 3 网络游戏通信方案3.1 强/弱弱联网游戏3.2 长/短连接游戏3.3 相关术语 1 数据通信模型 ​ 在早期的计算机网…...

路由器安全研究:D-Link DIR-823G v1.02 B05 复现与利用思路

前言 D-Link DIR-823G v1.02 B05存在命令注入漏洞,攻击者可以通过POST的方式往 /HNAP1发送精心构造的请求,执行任意的操作系统命令。 漏洞分析 binwalk提取固件,成功获取到固件。 现在我们已经进入到应用里了,那么我们在进行分析…...

【蓝桥杯python研究生组备赛】005 数学与简单DP

题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…...

数据仓库是什么,跟数据集成有什么关系

在当今数字化时代,数据已成为企业决策的重要依据。数据仓库作为企业数据管理的核心组件,其重要性不言而喻。那么,数据仓库到底是什么?它与数据集成又有着怎样的关系呢?本文将深入探讨这些问题。 一、数据仓库&#xf…...

鸿蒙NEXT项目实战-百得知识库01

代码仓地址,大家记得点个star IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点: 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三…...

【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解

目录 一、前言 二、Langchain4j概述 2.1 Langchain4j 介绍 2.1.1 Langchain4j 是什么 2.1.2 主要特点 2.2 Langchain4j 核心组件介绍 2.3 Langchain4j 核心优势 2.4 Langchain4j 核心应用场景 三、SpringBoot 整合 LangChain4j 组件使用 3.1 前置准备 3.1.1 获取apik…...

rust学习笔记16-206.反转链表(递归)

rust函数递归在14中已经提到,接下来我们把206.反转链表,用递归法实现 递归函数通常包含两个主要部分: 基准条件(Base Case):递归终止的条件,避免无限递归。 递归步骤(Recursive Ste…...

Unity 中实例化预制体的完整过程

1.资源加载(Load Asset to Memory) Unity 的资源加载是指将各种资源(如模型、纹理、音频、预制体 等)从存储介质(如磁盘、AssetBundle、远程服务器)到运行时内存的过程,使其成为可用的资源&…...

Unity动画片段丢失(AnimationClip),如何进行重新绑定

从外部导入的AnimationClip存在黄色丢失的missing提示,这时候不需要重新制作动画,只需要重新绑定动画即可。 我们以第一条Intro1:Anchored Position(缺失!)为例 第一步:双击动画中的Intro1条目,可以查看片段存储该动画的对应路径…...

mysql5.7主从部署(docker-compose版本)

mysql5.7主从部署(docker-compose版本) 1:docker-compose-test.yml 文件信息 version: 3services:# MySQL 数据库mysql-master:image: mysql:5.7container_name: mysql-masterenvironment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: nacosports:- 23…...

模型部署实战:PyTorch生产化指南

‌一、为什么要做模型部署?‌ 模型部署是将训练好的模型‌投入实际应用‌的关键步骤,涉及: 模型格式转换(TorchScript/ONNX)性能优化(量化/剪枝)构建API服务移动端集成 本章使用ResNet18实现图…...

SQLMesh 系列教程:Airbnb数据分析项目实战

在本文中,我们将探讨如何利用dbt项目的代码库来实现一个简单的SQLMesh项目。本文的基础是基于Udemy讲师为dbt课程创建的示例项目,可以在这个GitHub repo中获得。这个dbt项目是相对完整的示例,我们将使用它作为模板来演示SQLMesh(下…...

LeetCode hot 100 每日一题(11)——189. 轮转数组

这是一道难度为中等的题目,让我们来看看题目描述: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3…...

VLAN综合实验

一、实验拓扑 二、实验要求 1、PC1/3处于同一个网段,所在接口为access,属于VLAN 2。 2、PC2/4/5/6处于同一网段。 3、PC2可以访问PC4/5/6。 4、PC4可以访问PC5,但不能访问PC6。 5、PC5不能访问PC6。 6、所有PC通过DHCP获取IP地址&#…...

杨辉三角(js实现,LeetCode118)

看到这道题我的第一反应是找规律,核心突破点是numRows这个参数,杨辉三角的第numRows行拥有的元素数量为numRows个,并且头尾都是1,由此我们可以通过双层for循环,先生成每一行的数组,然后将每一行的数组push进…...

C语言复习笔记--数组

今天继续来浅浅推进一下C语言的复习,这次是数组的复习,话不多说,正文开始. 数组的概念 数组是⼀组相同类型元素的集合,一种自定义类型.数组中元素个数不能为0.数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组. 下面从一维数组说起. 一维数组的创建和…...

Linux操作系统实验报告单(3)文本编辑器vi/vim

一、实验目的 掌握vi/vim编辑器的进入和退出方式了解vi/vim的三种模式熟练vi/vim的操作命令 二、实验内容 1.在家目录下新建一个名为“vitest_name”(“name”为学生姓名拼音)的目录。 ●创建用户目录命令:sudo mkdir /home/vitest_lw3613 …...

docker linux 常用操作命令

以下是 Docker 的常见操作命令及其简单介绍,帮助你快速上手 Docker 的基本使用: 1. 镜像操作 拉取镜像 docker pull 镜像名称:标签示例: docker pull ubuntu:20.04从 Docker Hub 拉取 Ubuntu 20.04 镜像。 拉取镜像 docker build -t"…...

除自身以外数组的乘积——面试经典150题(力扣)

题目 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时…...

打破煤矿通信屏障,无线系统赋能生产安全与智能进阶

项目背景 在煤矿行业智能化转型的浪潮中,七台河矿业局积极回应国家煤矿智能化建设的号召,采取了具有前瞻性的战略举措——在七台河地区的煤矿部署了“井上井下”无线覆盖与广播一体化系统。此举旨在消除井上与井下之间的通信障碍,加强矿业局与…...

DeepSeek + Kimi 自动生成 PPT

可以先用deepseek生成ppt大纲,再把这个大纲复制到Kimi的ppt助手里: https://kimi.moonshot.cn/kimiplus/conpg18t7lagbbsfqksg 选择ppt模板: 点击生成ppt就制作好了。...

Blender标注工具

按住键盘D键 鼠标左键绘制 / 右键擦除 也可以在上方选择删除...

鸿蒙开发:远场通信服务rcp拦截器问题

前言 本文基于Api13。 上篇文章,简单的对rcp中的会话问题做了概述,本篇文章,我们聊一聊rcp中的拦截器问题,按照正常开发,其实拦截器中也不存在问题的,毕竟都是很官方的开发方式,但是在结合了创建…...

调研报告:Hadoop 3.x Ozone 全景解析

Ozone 是 Hadoop 的分布式对象存储系统,具有易扩展和冗余存储的特点。 Ozone 不仅能存储数十亿个不同大小的对象,还支持在容器化环境(比如 Kubernetes)中运行。 Apache Spark、Hive 和 YARN 等应用无需任何修改即可使用 Ozone。Ozone 提供了 Java API、S3 接口和命令行接口…...

Thinkphp 多文件压缩

控制器 <?phpnamespace app\api\controller; use think\Controller; use think\facade\Db; use think\facade\Request;use ZipArchive;class DrugTestResult {public function download(){if(Request::isPost()){$data Request::post();$idnumber Request::param(idnumb…...

NGINX中的反向代理实践

以下是一个全面和优化的配置示例&#xff0c;包括了错误处理、超时设置、头部信息调整等&#xff1a; server {listen 80;server_name your.domain.name; # 替换为你的实际域名或IP地址# 前端应用的静态资源处理location / {root /path/to/vue/dist; # Vue 应用的dist目录try_…...

redis分布式锁实现Redisson+redlock中watch dog是如何判断当前线程是否持有锁进行续租的呢?

在 Redis 中&#xff0c;Watch Dog&#xff08;看门狗&#xff09;机制主要用于实现分布式锁的自动续期&#xff08;如 Redisson 的 RedLock 实现&#xff09;。其核心目的是确保当业务逻辑执行时间超过锁的初始过期时间&#xff08;leaseTime&#xff09;时&#xff0c;锁不会…...

[spring] Spring JPA - Hibernate 多表联查 1

[spring] Spring JPA - Hibernate 多表联查 1 之前在 [spring] spring jpa - hibernate 名词解释&配置 和 [spring] spring jpa - hibernate CRUD 简单的学习了一下怎么使用 Hibernate 实现 CRUD 操作&#xff0c;不过涉及到的部分都是逻辑上比较简单的实现——只在一张表…...

在 Elasticsearch 中探索基于 NVIDIA 的 GPU 加速向量搜索

作者&#xff1a;来自 Elastic Chris Hegarty 及 Hemant Malik 由 NVIDIA cuVS 提供支持&#xff0c;此次合作旨在为开发者在 Elasticsearch 中的向量搜索提供 GPU 加速。 在 Elastic Engineering 组织内&#xff0c;我们一直致力于优化向量数据库的性能。我们的使命是让 Lucen…...

2025年图生视频模型技术全景解析

一、开源图生视频模型 阿里通义万象Wan2.1系列 I2V-14B-480P&#xff1a; 14B参数基础模型支持480P分辨率图生视频显存需求16GB以上 I2V-14B-720P&#xff1a; 高清增强版模型采用分帧渲染技术&#xff0c;输出分辨率达1280720 技术特性&#xff1a; 支持中文提示词自动解析内置…...

Docker build 会在本地产生巨大的文件

Docker build 会在本地产生巨大的文件&#xff0c; 比如 用 这个命令列出本地镜像 docker images 可见size都是很大的&#xff0c; 到docker目录下&#xff0c;看到ext4.vhdx的大小 80多G 那只能用这个命令把不用的镜像删掉了&#xff1a; &#xff08;rmi后面是镜像id&a…...

使用LLaMA Factory微调导出模型,并用ollama运行,用open webui使用该模型

本篇记录学习使用llama factory微调模型的过程&#xff0c;使用ollama运行微调好的模型&#xff0c;使用open webui前端调用ollama的模型&#xff1b; 测试机信息&#xff1a; 系统&#xff1a;Ubuntu 24.04.2 LTS&#xff08;桌面版&#xff09; cpu&#xff1a;i9-14900KF …...

Git远程拉取和推送配置

Git进行远程代码拉取和推送时候提示配置user.name 和 user.email 背景&#xff1a;换新电脑后使用Git进行代码拉取和推送过程中&#xff0c;提示“Make sure you configure your “user.name” and “user.email” in git.”。这个配置针对git的正常使用仅需要配置一次&#xf…...

正则魔法:解码 return /^\d+$/.test(text) ? text : ‘0‘ 的秘密

&#x1f680; 正则魔法&#xff1a;解码 return /^\d$/.test(text) ? text : 0 的秘密 &#x1f31f; 嘿&#xff0c;技术探险家们&#xff01;&#x1f44b; 今天我们要破解一段看似简单的代码&#xff1a;return /^\d$/.test(text) ? text : 0。它藏在一个 Vue 前端组件中…...

[023-01-47].第47节:组件应用 - GetWay与 Sentinel 集成实现服务限流

SpringCloud学习大纲 一、需求说明&#xff1a; 实现网关cloudalibaba-sentinel-gateway9528模块保护cloudalibaba-provider-payment9001 二、编码实现&#xff1a; 2.1.建module: 新建模块&#xff0c;名称是&#xff1a;cloudalibaba-sentinel-gateway9528 2.2.改pom &l…...

【自用】NLP算法面经(5)

一、L1、L2正则化 正则化是机器学习中用于防止过拟合并提高模型泛化能力的技术。当模型过拟合时&#xff0c;它已经很好地学习了训练数据&#xff0c;甚至是训练数据中的噪声&#xff0c;所以可能无法在新的、未见过的数据上表现良好。 比如&#xff1a; 其中&#xff0c;x1和…...

AI视频生成产品体验分享(第2趴):Vidu、Hailuo、Runway、Pika谁更胜一筹?

hi&#xff0c;大家&#xff0c;继上次体验完可灵、即梦和pixverse&#xff0c;今天打算从产品经理的角度再研究下Vidu、Hailuo、Runway、Pika这几款产品&#xff01;欢迎加入讨论&#xff01; 一、产品简介 1. Vidu&#xff1a;国产自研的「一致性标杆」 &#x1f4cc;官网…...

火绒终端安全管理系统V2.0——行为管理(软件禁用+违规外联)

火绒终端安全管理系统V2.0&#xff1a;行为管理策略分为软件禁用和违规外联两部分&#xff0c;能够管理终端用户软件的使用&#xff0c;以及终端用户违规连接外部网络的问题。 l 软件禁用 软件禁用策略可以选择软件名单的属性、添加软件名单以及设置发现终端使用禁用软件时的…...

台式机电脑组装---电脑机箱与主板接线

台式机电脑组装—电脑机箱与主板接线 1、机箱连接主板的跳线一般主要有USB 2.0、USB 3.0、前置音频接口(HD_AUDIO)以及POWER SW、RESET SW、POWER LED、HDD LED四个主板跳线&#xff0c;这些跳线分别的含义如下。 RESET SW&#xff1a;机箱重启按键&#xff1b;注&#xff1a…...

【总结】常用API架构类型

引言 在现代软件开发中&#xff0c;API(应用程序编程接口)已经成为各类系统之间交互的核心。不同的 API 架构类型适用于不同的业务需求和技术场景&#xff0c;选择合适的架构可以提高系统的性能、可维护性和扩展性。本文将介绍几种常见的 API 架构类型&#xff0c;并分析它们的…...

ffmpeg库视频硬解码使用流程

FFmpeg 的硬解码&#xff08;Hardware Decoding&#xff09;通过调用 GPU 或专用硬件的编解码能力实现&#xff0c;能显著降低 CPU 占用率。 ‌一、FFmpeg 支持的硬件解码类型‌ FFmpeg 原生支持多种硬件加速类型&#xff0c;具体由 AVHWDeviceType 定义&#xff0c;包括&…...

两个常用的用于读写和操作DXF文件C#库:netDxf 和 DXF.NET

netDxf 和 DXF.NET 是两个常用的C#库&#xff0c;用于读取、写入和操作DXF文件。以下是它们的详细介绍和用法示例。 1. netDxf 简介 netDxf 是一个开源的DXF文件读写库&#xff0c;支持AutoCAD DXF格式的读取和写入。它支持大多数DXF实体和对象&#xff0c;并且易于使用。 Gi…...

jmeter吞吐量控制器-Throughput Controller

jmeter吞吐量控制器-Throughput Controller 新增吞吐量控制器名词解释测试场景场景1&#xff1a;场景2&#xff1a;场景3场景4场景5场景6场景7场景8 测试结论 根据百分比执行不同的接口测试场景测试结果 新增吞吐量控制器 名词解释 Based on: Total Executions(总执行数)/Perc…...