一、负载均衡
早期的网站流量和业务功能都比较简单,单台服务器足以满足基本的需求,
但是随着互联网的发展,业务流量越来越大并且业务逻辑也跟着越来越复
杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器
进行性能的水平扩展及避免单点故障出现。
负载均衡是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响
应足够快,给用户很好的体验,快速增长的访问量和数据流量催生了各式各
样的负载均衡的产品,很多专业的的负载均衡硬件提供了很好的功能,但价
格不菲,这使得负载均衡软件大受欢迎,nginx就是其中一个,在linux下有
nginx、Ivs、haproxy等服务,可以提供复杂均衡服务。
二、负载均衡原理
负载均衡NAT(Network Address Translation网络地址转换)简单地说就
是将一个IP地址转换为另一个IP地址,一般用于未经注册的内部地址与合法
的、已获注册的Internet IP地址间进行转换。适用于解决Internet IP地址紧
张、不想让网络外部知道内部网络结构等的场合下。
系统的扩展可以分为纵向扩展和横向扩展。
纵向扩展:从单机的角度出发,通过增加系统的硬件处理能力来提升服
务器的处理能力;
横向扩展:通过添加机器来满足大型网站服务的处理能力。这里面涉及到两个重要的角色分别是“应用集群”和“负载均衡器
应用集群:将同一应用部署到多台机器上,组成处理集群,接收负载均
衡设备分发的请求,进行处理并返回响应的数据。
负载均衡器:将用户访问的请求根据对应的负载均衡算法,分发到集群
中的一台服务器进行处理。
三、负载均衡的作用
解决服务器的高并发压力,提高应用程序的处理性能;
提供故障转移,实现高可用;
通过添加或减少服务器数量,增强网站的可扩展性;
在负载均衡器上进行过滤,可以提高系统的安全性;
1、提高系统性能
负载均衡可以扩展网络设备和服务器的带宽,优化访问请求在服务器组之间
的分配,提高系统的反应速度和总体性能。2、监控服务器的运行状态
负载均衡能够监控服务器的运行状态,提高整个服务器组的可靠性。
3、提供服务一致性
负载均衡器具有提供服务一致性的功能,负载均衡器通过读取客户端所发出
请求内的信息,进行重写报头程序然后将请求发送至合适的服务器上,该服
务器会维护着该客户端信息。在http通信当中,负载均衡器提供服务一致性
的功能就得到了很好的发挥,但提供该服务的途径并不是非常安全。但若将
消息加密后,负载均衡器就无法读取隐藏其中的信息了。
4、摆脱停机时间
服务器托管公司可能会在维护期间将服务器关闭一段时间,这可能发生在业
务的高峰期。在基于云服务器中,可以在将流量引导到另一台服务器的资源
之后进行维护,前提是它们不在维护中,从而可以消除网站的停机时间。
5、管理服务器故障
由于它具有根据需要添加或删除实例的功能,因此可以跨云平台拥有多个数
据中心。如果其中一台服务器发生故障,则可以快速移动流量,将故障服务
器的流量流入到另一台服务器中。
6、转发功能
按照一定的算法,将客户端请求转发到不同应用服务器上,减轻单个服务器
压力,提高系统并发量。
7、恢复添加
如检测到发生故障的应用服务器恢复工作,自动将其添加到处理用户请求队
伍中。
8、分发流量
分发流量、请求到不同的服务器。使流量平均分配,提高整个集群的响应速
度、服务的高可用性。四、负载均衡常用处理方式
负载均衡分为四层负载均衡和七层负载均衡。
1. 四层负载均衡是工作在 OSI 七层协议的第四层——传输层,基于
IP+PORT的负载均衡,主要工作是转发。
2. 它在接收到客户端的流量以后通过修改数据包的地址信息(目标地址和
端口和源地址)将流量转发到应用服务器。
3. 实现四层负载均衡的方式:
硬件:F5、BIG-IP、Radware等;
软件:LVS、Nginx、Haproxy等。
1. 七层负载均衡是工作在七层协议的第七层-应用层,基于虚拟的URL或主
机IP的负载均衡,主要工作是代理。
2. 它首先会与客户端建立一条完整的连接并将应用层的请求流量解析出
来,再按照调度算法选择一个应用服务器,并与应用服务器建立另外一
条连接将请求发送过去。
3. 实现七层负载均衡的方式:
软件:Nginx、Hayproxy等。
五、四层和七层负载均衡的区别
1. 四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则
在最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的效率要
高;
2. 四层负载均衡不识别域名,而七层负载均衡识别域名。
3. 除了四层和七层负载均衡以外其实还有二层、三层负载均衡。二层负载
均衡是在数据链路层基于MAC地址来实现负载均衡,三层是在网络层一
般采用虚拟IP地址的方式实现负载均衡。
4. 实际环境采用的方式:四层负载 (LVS) +七层负载 (Nginx)六、nginx 七层负载均衡
1、七层负载均衡基础配置
2、负载均衡状态
[root@server]# vim /usr/local/nginx/conf/nginx.conf
worker_processes 1;
event {
worker_connections 1024;
}
http { # 七层负载均衡支持http、ftp协议
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream qicengzu { # 服务器组,组名qingcengzu
server 192.168.33.11:8080; # 组内服务器1
server 192.168.33.22:8080; # 组内服务器2
}
server { # 虚拟服务器
listen 80; # 虚拟服务器端口
server_name localhost; # 虚拟服务器名
location { # 虚拟服务器的url跳转
proxy_pass http://qicengzu;
# 当访问本机的80端口时,跳转到服务器组
}
}
}在服务器组的组内服务器后填写该服务器的状态,如:
3、负载均衡策略
(1)轮询
(2)weight 加权
[root@server]# vim /usr/local/nginx/conf/nginx.conf
......省略部分内容......
upstream qicengzu { # 服务器组,组名qingcengzu
server 192.168.33.11:8080 down; # 停止
此服务器负载均衡
server 192.168.33.22:8080 backup; # 该服
务器作为其他组内服务器的备份服务器
server 192.168.....
}
......省略部分内容......
upstream backend {
server 192.168.33.11:8080;
server 192.168.33.22:8080;
}
upstream backend {
server 192.168.33.11:8080 weight=5;
server 192.168.33.22:8080 weight=2; # 权重默认为
1,谁权重大,谁优先处理请求
}(3)ip_hash
当对后端的多台动态应用服务器做负载均衡时,ip_hash指令能够将某
个客户端IP的请求通过哈希算法定位到同一台后端服务器上。
这样,当来自某一个IP的用户在后端Web服务器A上登录后,再访问该
站点的其他URL,能保证其访问的还是后端web服务器A。
注意: 使用ip_hash指令无法保证后端服务器的负载均衡,可能导致有些
后端服务器接收到的请求多,有些后端服务器接受的请求少,而且设置
后端服务器权重等方法将不起作用
(4)least_conn
least_conn:最少连接,把请求转发给连接数较少的后端服务器。轮询
算法是把请求平均地转发给各个后端,使它们的负载大致相同;但是,
有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况
下,leastconn这种方式就可以达到更好的负载均衡效果。
(5)url_hash
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务
器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的
服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时
间的浪费。而使用ur_hash,可以使得同一个url (也就是同一个资源请
求)会到达同一台服务器,一旦缓存住了资源,再次收到请求,就可以从
缓存中读取。
upstream backend {
ip_hash; # ip_hash算法
server 192.168.33.11:8080;
server 192.168.33.22:8080;
}
upstream backend {
least_conn; # 将请求转发给连接数较少的后端服务器
server 192.168.33.11:8080;
server 192.168.33.22:8080;
}七、nginx 四层负载均衡
四层使用 stream 模块,与七层的 http 模块同级。
upstream backend {
hash $request_uri;
server 192.168.33.11:8080;
server 192.168.33.22:8080;
}
[root@localhost ~]# nginx -V # 查看版本及安装模块
nginx version: nginx/1.22.1
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-16) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021TLS SNI support
enabled
configure arguments: --prefix=/usr/local/nginx --
user=nginx --group=nginx--with-httpssl module --with
http_stub status_module --with-http_realip module
[root@localhost ~]# cp /usr/local/nginx/sbin/nginx
/usr/local/nginx/sbin/nginxbak #将原
有/usr/local/nginx/sbin/nginx进行备份
[root@localhost ~]# cd /usr/src/nginx-1.22.1/
[root@localhost nginx-1.22.1]# Is
auto CHANGES CHANGES.ru configure html Makefile objs
conf contrib LICENSE man README src
[root@localhost nginx-1.22.1]# ./configure --
prefix=/usr/local/nginx --user=nginx --group=nginx --with
http_ssl_module --with-http_stub_status_module --with
http_realip_module --with-stream # 安装指定模块
[root@localhost nginx-1.22.1]# make # 进行编译
[root@localhost nginx-1.22.1]# cp ./objs/nginx
/usr/local/nginx/sbin/ # 将obis下面的nginx移动
到/usr/local/nginx/sbin下
[root@localhost nginx-1.22.1]# nginx -V # 模块添加成功
nginx version: nginx/1.22.1
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-16) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021TLS SNI support
enabledconfigure arguments: --prefix=/usr/local/nginx --
user=nginx --group=nginx--with-httpssl module --with
http_stub status_module --with-http_realip module --with
stream
[root@server ~]# vim /usr/local/nginx/conf/nginx.conf
events {
worker_connections 1024;
}
stream {
upstream dongtai { # 配置dongtai服务器组
server 192.168.33.11:8080; # 动态资源走tomcat的
8080端口
server 192.168.33.22:8080;
}
server {
listen 81; # 设置监听端口
proxy_pass dongtai; # 当请求访问到本机的81端口时,
将请求转发到dongtai组
}
upstream jingtai { # 配置jingtai服务器组
server 192.168.33.33:80; # 静态资源走nginx或
tomcat的80端口
server 192.168.33.44:80;
}
server {
listen 82;
proxy_pass jingtai;
}
}
:wq
不停用业务,使用平滑升级
需要有kill命令的支持
kill不仅仅用于杀死进程,还可以向软件进程发送信号
常用的-9和-15一个是强杀,一个是正常杀
kill 信号 进程编号
-USR2
平滑启动一个进程,平滑升级
-WINCH 优雅关闭子进程
-QUIT
优雅关闭主进程
步骤
1.不停止原有服务,但是必须使用原生方式启动或者更改nginx脚本(会创
建一个新的进程)
2.重新编译nginx新版本
3.使用kill -USR@ 启动新版本
4.把旧的Nginx子进程全部退出
5.优雅的退出Nginx的老进程 系统就只剩下新的nginx了
使用原生方式启动nginx
# 重新加载nginx配置文件
sbin/nginx -c /usr/local/nginx/conf/nginx.conf查看进程,分主进程和work进程
# 查看进程
[root@front logs]# ps -aux|grep nginx
root 1277 0.0 0.1 46128 1156 ? Ss 7月29
0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 1278 0.0 0.2 46584 2148 ? S 7月29
0:00 nginx: worker process
root 1405 0.0 0.0 112828 988 pts/1 R+ 00:10
0:00 grep --color=auto nginx
上传新的版本并且解压
root@front logs]# cd
[root@front ~]# ls
anaconda-ks.cfg initserver.sh nginx-1.26.1 nginx-
1.26.1.tar.gz
[root@front ~]# wget https://nginx.org/download/nginx-
1.27.0.tar.gz
--2024-07-30 00:16:33-- https://nginx.org/download/nginx-
1.27.0.tar.gz
正在解析主机 nginx.org (nginx.org)... 52.58.199.22,
3.125.197.172, 2a05:d014:5c0:2601::6, ...
正在连接 nginx.org (nginx.org)|52.58.199.22|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:1244887 (1.2M) [application/octet-stream]
正在保存至: “nginx-1.27.0.tar.gz”
100%
[=========================================================
=============>] 1,244,887 115KB/s 用时 7.6s
2024-07-30 00:16:42 (160 KB/s) - 已保存 “nginx-
1.27.0.tar.gz” [1244887/1244887])
[root@front ~]# lsanaconda-ks.cfg initserver.sh nginx-1.26.1 nginx-
1.26.1.tar.gz nginx-1.27.0.tar.gz
[root@front ~]# tar -zxvf nginx-1.27.0.tar.gz
nginx-1.27.0/
...省略
nginx-1.27.0/man/nginx.8
[root@front ~]# ls
anaconda-ks.cfg initserver.sh nginx-1.26.1 nginx-
1.26.1.tar.gz nginx-1.27.0 nginx-1.27.0.tar.gz
对新版本进行编译安装,安装目录必须和旧版本一致
[root@front ~]# cd nginx-1.27.0/
[root@front nginx-1.27.0]# ./configure --
prefix=/usr/local/nginx --user=nginx --group=nginx --with
http_ssl_module --with-http_stub_status_module --with
http_realip_module --with-stream
[root@front nginx-1.27.0]# make && make install
使用kill -USR2 启用新版本的Nginx的软件
kill -USR2 老版本的pid编号
主要功能会根据上一次的启动方式再重新运行一次之前的启动命令
重装新的版本以后,会出现新的启动工具[root@front nginx-1.27.0]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.27.0
[root@front nginx-1.27.0]# /usr/local/nginx/sbin/nginx.old
-v
nginx version: nginx/1.26.1
再次查看进程,找到老版本的pid
[root@front nginx-1.27.0]# ps -ef|grep nginx
root 1277 1 0 7月29 ? 00:00:00 nginx:
master process /usr/local/nginx/sbin/nginx
nginx 1278 1277 0 7月29 ? 00:00:00 nginx:
worker process
root 4412 1281 0 00:33 pts/1 00:00:00 grep --
color=auto nginx
# 使用老的nginx进程创建新的进程
[root@front nginx-1.27.0]# kill -USR2 1277
[root@front nginx-1.27.0]# ps -ef|grep nginx
root 1277 1 0 7月29 ? 00:00:00 nginx:
master process /usr/local/nginx/sbin/nginx
nginx 1278 1277 0 7月29 ? 00:00:00 nginx:
worker process
root 4413 1277 0 00:34 ? 00:00:00 nginx:
master process /usr/local/nginx/sbin/nginx
nginx 4414 4413 0 00:34 ? 00:00:00 nginx:
worker process
root 4418 1281 0 00:34 pts/1 00:00:00 grep --
color=auto nginx
此时会出现两套master进程,这个时候处理客户请求的就是新的nginx服务
了
关闭老版本的所有子进程
关闭老版本的主进程[root@front nginx-1.27.0]# kill -WINCH 1278
[root@front nginx-1.27.0]# kill -QUIT 1277
[root@front nginx-1.27.0]# ps -ef|grep nginx
root 4413 1 0 00:34 ? 00:00:00 nginx:
master process /usr/local/nginx/sbin/nginx
nginx 4414 4413 0 00:34 ? 00:00:00 nginx:
worker process
root 4424 1281 0 00:40 pts/1 00:00:00 grep --
color=auto nginx
使用curl 查看当前服务器的版本
[root@front nginx-1.27.0]# curl -I localhost
HTTP/1.1 403 Forbidden
Server: nginx/1.27.0
Date: Mon, 29 Jul 2024 16:42:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 153
Connection: keep-alive