1.nginx介绍
1.1nginx的架构

nginx采用多进程架构,由一个主进程(master)和多个工作进程(worker)组成,主进程负责管理配置加载,信号处理及worker进程创建;worker进程处理实际请求,基于实际驱动高校并发,支持数万连接,还可以包含缓存进程等,整体轻量高效,适用于高并发场景
1.2nginx的模块
nginx模块化设计可定制功能,分为核心与第三方模块
核心模块包含处理事件的events,处理http的httpmodule及access,ssl,rewrite等子模块,还有fastcgi,proxy等功能模块,以及mailmodule
第三方模块可扩展http,过滤请求响应,实现负载均衡
1.3nginx的版本
nginx一共分为mainline,stable,legacy三类版本
mainline是主线版,主要用于开发方向
stable是稳定版,主要比较稳定,用着比较放心,没有那么多bug
legacy是已经归档的版本,尽量不要用
2.nginx的安装
2.1yum安装nginx
bash
[root@nginx ~]# yum install nginx -y
#查看版本
[root@nginx ~]# nginx -v
nginx version: nginx/1.20.1
2.2源码编译安装nginx
2.2.1安装nginx所需的pcre库
安装pere库是为了使nginx支持具备URI重写功能的rewrite模块,如果不安装pere库,则nginx无法使用rewrite模块功能,nginx的rewrite模块功能几乎是企业应用必须的
bash
[root@rhel9-nginx ~]# yum install -y pcre-devel
2.2.2安装openssl-devel
nginx在使用https服务的时候要用到此模块,如果不安装openssl相关包,安装nginx的过程中会报错
bash
[root@rhel9-nginx ~]# yum install -y openssl-devel
2.2.3源码安装nginx
a.安装编译器和压缩所需要的库
bash
[root@rhel9-nginx ~]# yum install gcc zlib-devel -y
b.创建一个名为nginx的系统用户
bash
[root@nginx ~]# useradd nginx -s /sbin/nologin -M
c.切换到/opt/并通过xftp上传nginx包

d.编译安装nginx
bash
[root@rhel9-nginx opt]# cd nginx-1.24.0/
[root@rhel9-nginx nginx-1.24.0]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
--user=nginx:指定Nginx工作进程运行的用户为nginx
--group=nginx:指定Nginx工作进程运行的用户组为nginx
--prefix=/usr/local/nginx:设置Nginx的安装目录为/usr/local/nginx
--with-http_stub_status_module:启用HTTP状态监控模块
--with-http_ssl_module:启用HTTPS支持
--with-http_v2_module:启用HTTP/2协议支持
--with-http_realip_module:启用获取客户端真实IP模块
--with-http_gzip_static_module:启用静态资源gzip压缩模块
--with-pcre:启用PCRE库支持
--with-stream:启用stream模块
--with-stream_ssl_module:为stream模块启用SSL支持
--with-stream_realip_module:为stream模块启用真实IP支持
e.编译并安装
bash
[root@rhel9-nginx nginx-1.24.0]# make && make install
f.编译成功后查看软件信息
bash
[root@rhel9-nginx ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.24.0
built by gcc 11.4.1 20230605 (Red Hat 11.4.1-2) (GCC)
built with OpenSSL 3.0.7 1 Nov 2022
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
2.2.4启动nginx
a.第一种
创建软链接
bash
[root@rhel9-nginx nginx-1.24.0]# ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx
[root@rhel9-nginx nginx-1.24.0]# ll /usr/sbin/nginx
lrwxrwxrwx 1 root root 27 9月 13 03:32 /usr/sbin/nginx -> /usr/local/nginx/sbin/nginx
启动nginx
bash
[root@rhel9-nginx nginx-1.24.0]# /usr/local/nginx/sbin/nginx
查看进程
bash
[root@rhel9-nginx nginx-1.24.0]# ss -lntup | grep 80
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=37989,fd=6),("nginx",pid=37988,fd=6))
b.第二种
编写脚本使其systemctl启动nginx
bash
[root@rhel9-nginx nginx-1.24.0]# vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server #描述服务功能(Nginx HTTP 和反向代理服务器)
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking #服务启动方式为forking
PIDFile=/usr/local/nginx/logs/nginx.pid #指定Nginx主进程PID文件路径
ExecStartPre=/usr/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
启动nginx
bash
[root@rhel9-nginx nginx-1.24.0]# systemctl daemon-reload
[root@rhel9-nginx nginx-1.24.0]# systemctl enable --now nginx
查看进程
bash
[root@rhel9-nginx nginx-1.24.0]# ss -lntup | grep 80
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=38165,fd=6),("nginx",pid=38164,fd=6))
2.3nginx平滑升级和回滚
2.3.1概念
nginx的平滑升级是指在不中断服务的情况下进行软件版本或配置文件的更新,通过平滑更新,nginx能够在运行的时候应用新的配置或软件版本,继续处理请求,而不影响现有的连接
平滑升级的主要优势在于,它允许nginx在更新时保持对服务的连续响应,避免中断用户的请求,这对于具有高可用性要求的生产环境非常重要,但要注意的是,平滑升级并不适用与所有场景,特别在某些配置或软件更改可能导致不兼容性问题的情况下,在进行平滑升级之前,建议先在测试环境中进行充分的测试
接下来要用到的命令如下
bash
kill -usr2 #平滑升级启动新的master,主进程pid
kill -winch #告诉旧master结束worker,主进程pid
kill -quit #告诉旧master优雅退出,主进程pid
kill -hup #拉起旧master下面的worker,主进程pid
2.3.2平滑升级步骤
a.准备新版本程序/配置(确保无误)
b.替换旧资源(备份旧版本可以进行回滚)
c.向主进程发信号触发更新
d.主进程启动新工作进程
e.新连接由新进程处理,旧进程继续处理现有的连接
f.旧进程无活动连接后自动退出
2.3.3升级操作(旧的worker上有链接的情况)
a.准备好升级需要的版本的二进制文件
bash
[root@rhel9-nginx ~]# cd /opt/
[root@rhel9-nginx opt]# ll nginx-1.28.0.tar.gz
-rw-r--r-- 1 root root 1280111 9月 13 16:00 nginx-1.28.0.tar.gz
b.进行解压缩
bash
[root@rhel9-nginx opt]# tar xf nginx-1.28.0.tar.gz
c.编译nginx
bash
[root@rhel9-nginx opt]# cd nginx-1.28.0/
[root@rhel9-nginx nginx-1.28.0]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
--user=nginx:指定Nginx工作进程运行的用户为nginx
--group=nginx:指定Nginx工作进程运行的用户组为nginx
--prefix=/usr/local/nginx:设置Nginx的安装目录为/usr/local/nginx
--with-http_stub_status_module:启用HTTP状态监控模块
--with-http_ssl_module:启用HTTPS支持
--with-http_v2_module:启用HTTP/2协议支持
--with-http_realip_module:启用获取客户端真实IP模块
--with-http_gzip_static_module:启用静态资源gzip压缩模块
--with-pcre:启用PCRE库支持
--with-stream:启用stream模块
--with-stream_ssl_module:为stream模块启用SSL支持
--with-stream_realip_module:为stream模块启用真实IP支持
d.编译完nginx但是不要安装
bash
[root@rhel9-nginx nginx-1.28.0]# make
e.编译好的新版本nginx在objs目录下
bash
[root@rhel9-nginx nginx-1.28.0]# ./objs/nginx -v
nginx version: nginx/1.28.0
f.替换旧版本
bash
[root@rhel9-nginx nginx-1.28.0]# rm -f /usr/sbin/nginx
[root@rhel9-nginx nginx-1.28.0]# ln -s /opt/nginx-1.28.0/objs/nginx /usr/sbin/nginx
注意:
必须要先给旧版本nginx做备份
因为我们这里做的软链接,所有直接删除软链接,不会生产旧版本nginx
g.查看当前版本
bash
[root@rehl9-nginx nginx-1.28.0]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
h.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 42049 1 0 05:05 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 42050 42049 0 05:05 ? 00:00:00 nginx: worker process
i.向master进程发信号,此时会发现有两个master进程
平滑升级启动新的master
bash
[root@rhel9-nginx nginx-1.28.0]# kill -usr2 42049
查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 42049 1 0 05:05 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 42050 42049 0 05:05 ? 00:00:00 nginx: worker process
root 42061 42049 0 05:06 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 42062 42061 0 05:06 ? 00:00:00 nginx: worker process
j.模拟有一个大文件,旧的worker上有连接(需要开两个进程)
创建一个大文件
bash
[root@rhel9-nginx ~]# dd if=/dev/zero of=/usr/local/nginx/html/test bs=1M count=100
记录了100+0 的读入
记录了100+0 的写出
104857600字节(105 MB,100 MiB)已复制,0.295172 s,355 MB/s
客户端模拟下载大文件
bash
[root@rhel9-nginx ~]# wget --limit-rate=102400 192.168.75.184/test
--2025-09-13 04:37:04-- http://192.168.75.184/test
正在连接 192.168.75.184:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:104857600 (100M) [application/octet-stream]
正在保存至: "test"
test 8%[==> ] 8.48M 100KB/s 剩余 15m 38s
告诉旧master结束worker
bash
[root@rhel9-nginx nginx-1.28.0]# kill -winch 42049
查看进程,发现并没有动
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 42049 1 0 05:05 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 42050 42049 0 05:05 ? 00:00:00 nginx: worker process is shutting down
root 42061 42049 0 05:06 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 42062 42061 0 05:06 ? 00:00:00 nginx: worker process
将大文件停止
bash
[root@rhel9-nginx ~]# wget --limit-rate=102400 192.168.75.184/test
--2025-09-13 04:37:04-- http://192.168.75.184/test
正在连接 192.168.75.184:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:104857600 (100M) [application/octet-stream]
正在保存至: "test"
test 8%[==> ] 8.48M 100KB/s 剩余 15m 38s ^C
注意:如果此时旧的worker上有连接,给旧的master发送关闭进程信号,旧的master会等worker处理完工作后才会将其关闭
k.告诉旧master结束worker
bash
[root@rhel9-nginx nginx-1.28.0]# kill -winch 42049
l.告诉旧master优雅退出
bash
[root@rhel9-nginx nginx-1.28.0]# kill -quit 42049
m.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 42061 1 0 05:06 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 42062 42061 0 05:06 ? 00:00:00 nginx: worker process
n.查看版本是否更新
bash
[root@rhel9-nginx nginx-1.28.0]# curl -I 192.168.75.184
HTTP/1.1 200 OK
Server: nginx/1.28.0
Date: Sat, 13 Sep 2025 09:07:30 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Sat, 13 Sep 2025 07:25:03 GMT
Connection: keep-alive
ETag: "68c51c4f-267"
Accept-Ranges: bytes
2.3.4升级(业务没有问题,升级换代成功)
a.删除之前的软链接
bash
[root@rhel9-nginx nginx-1.28.0]# rm -f /usr/sbin/nginx
b.创建新的软链接
bash
[root@rhel9-nginx nginx-1.28.0]# ln -s /opt/nginx-1.28.0/objs/nginx /usr/sbin/nginx
c.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41831 1 0 04:48 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41832 41831 0 04:48 ? 00:00:00 nginx: worker process
d.平滑升级启动新的master
bash
[root@rhel9-nginx nginx-1.28.0]# kill -usr2 41831
e.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41831 1 0 04:48 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41832 41831 0 04:48 ? 00:00:00 nginx: worker process
root 41886 41831 0 04:52 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41887 41886 0 04:52 ? 00:00:00 nginx: worker process
f.告诉旧master结束worker
bash
[root@rhel9-nginx nginx-1.28.0]# kill -winch 41831
g.告诉旧master优雅退出
bash
[root@rhel9-nginx nginx-1.28.0]# kill -quit 41831
h.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41886 1 0 04:52 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41887 41886 0 04:52 ? 00:00:00 nginx: worker process
i.查看版本
bash
[root@rhel9-nginx nginx-1.28.0]# curl -I 192.168.75.184
HTTP/1.1 200 OK
Server: nginx/1.28.0
Date: Sat, 13 Sep 2025 08:53:45 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Sat, 13 Sep 2025 07:25:03 GMT
Connection: keep-alive
ETag: "68c51c4f-267"
Accept-Ranges: bytes
2.3.5降级(此时切换到新的master出现了问题,那么就回滚)
a.删除之前的软链接
bash
[root@rhel9-nginx nginx-1.28.0]# rm -f /usr/sbin/nginx
b.创建新的软链接
bash
[root@rhel9-nginx nginx-1.28.0]# ln -s /opt/nginx-1.28.0/objs/nginx /usr/sbin/nginx
c.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41938 1 0 04:56 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41939 41938 0 04:56 ? 00:00:00 nginx: worker process
d.平滑升级启动新的master
bash
[root@rhel9-nginx nginx-1.28.0]# kill -usr2 41938
e.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41938 1 0 04:56 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41939 41938 0 04:56 ? 00:00:00 nginx: worker process
root 41968 41938 0 04:58 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41969 41968 0 04:58 ? 00:00:00 nginx: worker process
f.告诉旧master结束worker
bash
[root@rhel9-nginx nginx-1.28.0]# kill -winch 41938
g.删除现在的软链接
bash
[root@rhel9-nginx nginx-1.28.0]# rm -f /usr/sbin/nginx
h.创建之前的软链接
bash
[root@rhel9-nginx nginx-1.28.0]# ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx
i.拉起旧master下面的worker
bash
[root@rhel9-nginx nginx-1.28.0]# kill -hup 41938
j.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41938 1 0 04:56 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
root 41968 41938 0 04:58 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41969 41968 0 04:58 ? 00:00:00 nginx: worker process
nginx 42006 41938 0 05:00 ? 00:00:00 nginx: worker process
k.告诉旧master结束worker
bash
[root@rhel9-nginx nginx-1.28.0]# kill -winch 41968
l.告诉旧master优雅退出
bash
[root@rhel9-nginx nginx-1.28.0]# kill -quit 41968
m.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41938 1 0 04:56 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 42006 41938 0 05:00 ? 00:00:00 nginx: worker process
n.查看版本是否成功回滚
bash
[root@rhel9-nginx nginx-1.28.0]# curl -I 192.168.75.184
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Sat, 13 Sep 2025 09:01:20 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Sat, 13 Sep 2025 07:25:03 GMT
Connection: keep-alive
ETag: "68c51c4f-267"
Accept-Ranges: bytes
2.3.6降级(已经完全升级成功,但是用了一会才发现兼容不了)
a.删除之前的软链接
bash
[root@rhel9-nginx nginx-1.28.0]# rm -f /usr/sbin/nginx
b.创建新的软链接
bash
[root@rhel9-nginx nginx-1.28.0]# ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx
c.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41886 1 0 04:52 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41887 41886 0 04:52 ? 00:00:00 nginx: worker process
d.平滑升级启动新的master
bash
[root@rhel9-nginx nginx-1.28.0]# kill -usr2 41886
e.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41886 1 0 04:52 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41887 41886 0 04:52 ? 00:00:00 nginx: worker process
root 41938 41886 0 04:56 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41939 41938 0 04:56 ? 00:00:00 nginx: worker process
f.告诉旧master结束worker
bash
[root@rhel9-nginx nginx-1.28.0]# kill -winch 41886
g.告诉旧master优雅退出
bash
[root@rhel9-nginx nginx-1.28.0]# kill -quit 41886
h.查看进程
bash
[root@rhel9-nginx nginx-1.28.0]# ps -ef | grep nginx | grep -v grep
root 41938 1 0 04:56 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 41939 41938 0 04:56 ? 00:00:00 nginx: worker process
i.查看版本
bash
[root@rhel9-nginx nginx-1.28.0]# curl -I 192.168.75.184
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Sat, 13 Sep 2025 08:57:00 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Sat, 13 Sep 2025 07:25:03 GMT
Connection: keep-alive
ETag: "68c51c4f-267"
Accept-Ranges: bytes