nginx源码安装以及平滑升级
Nginx 源码安装完整笔记(CentOS 8+/RHEL 8+)
一、安装前置说明
1. 适用环境
- 操作系统:CentOS 8+/RHEL 8+(用户使用
dnf包管理器,适配该系统系列) - Nginx 版本:1.26.3(稳定版,官网长期支持)
- 安装方式:源码编译(灵活定制模块,适合生产环境)
2. 前置检查
安装前确保系统无残留的 Nginx 包(避免冲突):
# 检查是否已安装 Nginx(如有则卸载)
rpm -qa | grep nginx
dnf remove nginx -y # 若存在残留,执行卸载
3. 核心依赖说明
Nginx 编译依赖以下库(用户已安装核心依赖,补充说明作用):
gcc-c++:C/C++ 编译器(编译 Nginx 源码必需)pcre-devel:PCRE 库开发文件(支持 Nginx 正则表达式匹配)openssl-devel:OpenSSL 库开发文件(支持 HTTPS/SSL 协议)zlib-devel:zlib 库开发文件(支持 HTTP 压缩功能)
二、完整安装步骤
步骤 1:准备源码目录
# 进入 Linux 常用源码存放目录(统一管理,方便后续维护)
cd /usr/local/src/
ll # 查看目录内容,确认无重复安装包
步骤 2:下载 Nginx 源码包
# 从 Nginx 官网下载稳定版源码包(推荐)
wget https://nginx.org/download/nginx-1.26.3.tar.gz# 补充:若 wget 下载失败(网络问题),可备用以下方案
# 1. 手动下载:打开官网 https://nginx.org/download/,下载后上传到 /usr/local/src/
# 2. 换国内镜像:wget http://mirrors.sohu.com/nginx/nginx-1.26.3.tar.gz
步骤 3:解压源码包
# 解压 tar.gz 包(参数含义:z=解压 gzip 格式,x=提取文件,v=显示详细过程,f=指定包文件)
tar -xzvf nginx-1.26.3.tar.gzll # 查看解压结果,会生成 nginx-1.26.3 目录(源码目录)
步骤 4:安装编译依赖
# CentOS 8+/RHEL 8+ 用 dnf 安装依赖(自动解决依赖关系)
dnf install -y gcc-c++ pcre-devel openssl-devel zlib-devel# 补充:若为 CentOS 7,将 dnf 替换为 yum:
# yum install -y gcc-c++ pcre-devel openssl-devel zlib-devel
# 若为 Ubuntu/Debian,依赖安装命令:
# apt update && apt install -y gcc g++ libpcre3-dev libssl-dev zlib1g-dev
步骤 5:配置编译参数(用户用默认配置,补充自定义优化)
# 进入源码目录
cd nginx-1.26.3/# 查看源码目录文件(确认 configure 脚本存在)
ls# 用户操作:默认配置(安装路径为 /usr/local/nginx)
./configure 可以在官网详细查看:https://nginx.org/en/docs/configure.html
# 补充:生产环境常用自定义配置(推荐)
# 自定义安装路径、启用常用模块、优化性能
./configure \
--prefix=/usr/local/nginx \ # 安装根目录(默认就是这个,可显式指定)
--user=nginx \ # 运行 Nginx 的用户(需提前创建:useradd -M -r -s /sbin/nologin nginx)
--group=nginx \ # 运行 Nginx 的组
--with-http_ssl_module \ # 启用 HTTPS 模块(必备)
--with-http_gzip_static_module \ # 启用 gzip 静态压缩模块
--with-http_stub_status_module \ # 启用状态监控模块(查看 Nginx 运行状态)
--with-stream \ # 启用 TCP/UDP 反向代理模块(如需代理数据库、Redis 等)
--worker_processes=auto # 工作进程数(自动适配 CPU 核心数)# 配置说明:执行 ./configure 后会生成 Makefile(编译配置文件),若报错则说明依赖缺失,需补装对应依赖
步骤 6:编译源码(补充加速编译)
# 编译源码(根据 Makefile 编译生成可执行文件)
make # 🌟 补充:多核心加速编译(利用 CPU 多核心,缩短编译时间)
# make -j $(nproc) # nproc 自动获取 CPU 核心数,如 4 核心则为 make -j 4
步骤 7:安装 Nginx
# 安装编译后的文件到指定目录(默认 /usr/local/nginx)
make install # 安装完成后,/usr/local/nginx 目录结构:
# sbin/:存放 nginx 主程序(启动/停止命令)
# conf/:配置文件目录(核心 nginx.conf)
# html/:默认网站根目录(存放静态页面)
# logs/:日志目录(访问日志、错误日志)
步骤 8:启动 Nginx
# 进入 Nginx 启动目录
cd /usr/local/nginx/sbin/
ls # 查看 nginx 主程序# ❌ 用户错误操作:. nginx 和 . /nginx(语法错误,会报错“没有那个文件或目录”)
# ✅ 正确启动命令(./ 表示执行当前目录下的程序)
./nginx # :创建全局软链接
# 无需每次进入 /usr/local/nginx/sbin/,直接在任意目录执行 nginx 命令
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx解释:
命令核心:ln -s
ln 是 "link"(链接)的缩写,用于在文件 / 目录间建立关联;
-s 是选项 "symbolic" 的缩写,指定创建软链接(而非硬链接),软链接类似 Windows 的 “快捷方式”,仅记录目标文件的路径,不复制实际内容。
参数含义
第一个参数 /usr/local/nginx/sbin/nginx:是目标文件路径(即 “源文件”),这里指 Nginx 服务器的可执行程序(Nginx 安装后默认的二进制文件位置);
第二个参数 /usr/bin/nginx:是软链接文件路径(即 “快捷方式” 的位置和名称),/usr/bin 是系统默认的 “可执行程序目录”,普通用户无需输入完整路径即可调用此目录下的程序。# 验证软链接是否生效(用户操作正确)
ll /usr/bin/nginx # 显示 lrwxrwxrwx. 1 root root 27 ... /usr/bin/nginx -> /usr/local/nginx/sbin/nginx
nginx # 直接执行 nginx 命令(启动服务)
让其能够全局访问的其他3种方法(除软连接)
除了软链接,确实还有 3 种核心方法 能让 Nginx 全局可用,本质都是围绕 Linux 的「$PATH 命令查找规则」—— 要么把 Nginx 程序路径加入 $PATH,要么让程序出现在 $PATH 已包含的目录中。以下是具体方法,按「推荐程度 + 实用性」排序,附操作步骤、优缺点和适用场景:
一、方法 1:直接修改 $PATH 环境变量(最推荐,无副作用)
核心逻辑:把 Nginx 真实程序所在目录(/usr/local/nginx/sbin/),直接加入系统的 $PATH 环境变量中。这样系统会自动在该目录下查找 nginx 命令,无需创建任何链接或复制文件。
操作步骤
1. 临时生效(仅当前终端有效,测试用)
直接执行 export 命令,立即生效:
# 格式:export PATH="$PATH:程序所在目录"
export PATH="$PATH:/usr/local/nginx/sbin/"
测试:在任意目录输入 nginx -v,能正常显示版本即生效。
2. 永久生效(所有终端 + 重启后有效,生产用)
需要把命令写入「环境变量配置文件」,根据需求选择全局生效(所有用户可用)或当前用户生效:
场景 A:仅当前用户(root)生效(推荐,不影响其他用户)
编辑用户级配置文件 ~/.bashrc:
# 打开配置文件
vim ~/.bashrc# 在文件末尾添加以下内容(换行添加,避免和其他配置冲突)
export PATH="$PATH:/usr/local/nginx/sbin/"# 保存退出后,让配置立即生效(无需重启)
source ~/.bashrc~/.bashrc 是当前用户的「终端启动配置文件」,默认情况下,只有重新打开终端时,系统才会加载里面的配置;
source ~/.bashrc 命令的作用是「强制重新加载该配置文件」,让新增的 PATH 配置立即生效,不用重启终端就能全局调用 nginx。核心原因是 Linux 的「命令查找规则」—— 系统会自动在 $PATH 环境变量指定的目录中搜索可执行命令。
场景 B:全局生效(所有用户均可使用)
编辑系统级配置文件 /etc/profile(需 root 权限):
# 打开系统配置文件
vim /etc/profile# 在文件末尾添加
export PATH="$PATH:/usr/local/nginx/sbin/"# 保存退出后,全局生效(所有已登录用户需重新登录,或执行 source )
source /etc/profile
验证是否生效
# 查看 $PATH 是否包含 Nginx 目录
echo $PATH | grep /usr/local/nginx/sbin# 任意目录执行 Nginx 命令
nginx -v # 正常输出版本即成功
优缺点
| 优点 | 缺点 |
|---|---|
| 无额外文件:不创建链接、不复制程序,仅修改环境变量,干净无残留 | 需编辑配置文件(步骤比软链接多 1 步) |
| 维护方便:后续升级 Nginx 只要目录不变,无需重新操作 | 若修改系统级配置(/etc/profile),可能影响其他用户 |
| 无兼容性问题:所有 Linux 发行版通用 | - |
适用场景:生产环境首选(比软链接更灵活,尤其适合多个源码安装软件)
二、方法 2:复制 Nginx 可执行程序到 $PATH 目录(不推荐,仅应急用)
核心逻辑:把 Nginx 真实的可执行程序(/usr/local/nginx/sbin/nginx),直接复制到 $PATH 已包含的目录(如 /usr/bin/、/usr/local/bin/),系统会直接识别。
操作步骤
# 复制 Nginx 程序到 /usr/bin/($PATH 默认包含该目录)
cp /usr/local/nginx/sbin/nginx /usr/bin/# 验证:任意目录执行
nginx -v
优缺点
| 优点 | 缺点 |
|---|---|
| 操作极简:1 条 cp 命令搞定,无需改配置 | 占用额外空间:复制了整个 Nginx 程序(几十 MB),软链接仅占几字节 |
| 立即生效:无需 source 或重启 | 维护麻烦:后续升级 Nginx 时,需要重新复制新程序到 /usr/bin/,否则仍用旧版本 |
| - | 可能冲突:若系统已通过 dnf/yum 安装过 Nginx,会覆盖原有程序 |
适用场景:临时应急(比如服务器无法创建软链接、改配置文件权限不足时),生产环境绝对不推荐(维护成本高)。
三、方法 3:创建硬链接(少见,介于软链接和复制之间)
核心逻辑:用 ln 命令创建「硬链接」(不加 -s 选项),硬链接是文件的「inode 引用」(和源文件共享存储,不占额外空间),且硬链接不依赖源文件路径(源文件移动后仍可用)。
操作步骤
# 格式:ln 源文件 目标路径(目标路径在 $PATH 目录中)
ln /usr/local/nginx/sbin/nginx /usr/bin/nginx-hard# 验证:任意目录执行硬链接命令
nginx-hard -v
硬链接 vs 软链接(关键区别)
| 特性 | 硬链接 | 软链接(你之前用的) |
|---|---|---|
| 依赖源路径 | 不依赖(源文件移动后仍可用) | 依赖(源文件路径变了,软链接失效) |
| 跨文件系统 | 不支持(源文件和硬链接必须在同一磁盘分区) | 支持 |
| 删除源文件 | 硬链接仍可用(inode 未删除) | 软链接失效(提示 “找不到文件”) |
| 适用场景 | 源文件路径可能变动,但不想频繁维护链接 | 大多数场景(灵活、跨分区、易识别) |
优缺点
| 优点 | 缺点 |
|---|---|
| 不占额外空间:和软链接一样仅占 inode 引用 | 不支持跨文件系统(比如源文件在 /data 分区,/usr/bin 在 / 分区,无法创建) |
| 源文件移动后仍可用 | 不易区分:硬链接看起来像独立文件,无法直观判断是链接(软链接用 ll 查看会显示箭头指向源文件) |
| - | 生产环境使用少:不如软链接灵活,不如修改 $PATH 通用 |
适用场景:源文件路径可能频繁变动(比如需要定期迁移程序目录),但跨分区场景不适用,日常用得极少。
四、方法 4:用 alias 命令设置别名(临时 / 个人使用)
核心逻辑:给 Nginx 完整路径设置「命令别名」,输入别名即可执行对应命令,本质是「命令替换」,不是真正的 “全局命令”(仅当前用户 / 终端生效)。
操作步骤
1. 临时生效(仅当前终端)
# 格式:alias 别名="完整命令路径"
alias ngx="/usr/local/nginx/sbin/nginx"# 验证:输入别名执行
ngx -v
ngx -s reload
2. 永久生效(仅当前用户)
把别名写入用户配置文件 ~/.bashrc:
# 编辑配置文件
vim ~/.bashrc# 末尾添加
alias ngx="/usr/local/nginx/sbin/nginx"# 生效
source ~/.bashrc
优缺点
| 优点 | 缺点 |
|---|---|
| 操作简单:无需创建文件、改 $PATH | 不是真正全局命令:仅对当前用户生效(其他用户登录后无法使用) |
| 可自定义别名:比如用 ngx 代替 nginx,更简洁 | 不支持管道 / 脚本调用:在 Shell 脚本中执行 ngx 会提示 “命令未找到”(脚本默认不加载 .bashrc 别名) |
| - | 冲突风险:若别名和系统命令重名(如 alias ls="xxx"),会覆盖原有命令 |
适用场景:个人使用(比如自己常用的服务器,想简化命令),不适合生产环境(脚本调用、多用户使用均受限)。
五、所有方法对比总结(推荐优先级)
| 方法 | 推荐度 | 核心优势 | 适用场景 |
|---|---|---|---|
| 软链接(你之前用的) | ⭐⭐⭐⭐⭐ | 灵活、跨分区、易维护、生产标准 | 绝大多数场景(首选) |
| 修改 $PATH 环境变量 | ⭐⭐⭐⭐⭐ | 无额外文件、维护方便、通用 | 生产环境(和软链接并列首选) |
| 硬链接 | ⭐⭐⭐ | 源文件移动后仍可用 | 源文件路径频繁变动的特殊场景 |
| alias 别名 | ⭐⭐ | 自定义别名、操作简单 | 个人临时使用、简化命令 |
| 复制程序 | ⭐ | 应急快、无需改配置 | 临时应急(生产环境禁用) |
最终建议
- 生产环境:优先选择「软链接」或「修改 $PATH 环境变量」(两者无本质区别,软链接更直观,修改 $PATH 更干净);
- 临时测试:用「alias 临时别名」或「复制程序」(应急用);
- 特殊场景(源文件路径变动):用「硬链接」(少见)。
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
先拆解命令:每个部分的含义
| 命令片段 | 作用说明 |
|---|---|
ln | Linux 中创建「链接文件」的核心命令(类似 Windows 的 “快捷方式”) |
-s | 选项:创建「软链接(符号链接,Symbolic Link)」,而非硬链接(硬链接是文件副本,软链接是路径引用) |
/usr/local/nginx/sbin/nginx | 「源文件」:Nginx 源码安装后,真实的可执行程序路径(核心程序,启动 / 停止 Nginx 全靠它) |
/usr/bin/nginx | 「目标链接」:要创建的软链接路径(放在系统默认的 “命令搜索目录” 里) |
简单说:这个命令是给「真实的 Nginx 程序」在 /usr/bin 目录下创建一个「全局快捷方式」。
最关键的特殊点:$PATH 环境变量的 “默认成员”
这是 /usr/bin 最核心的特殊之处 —— 它是系统「命令查找路径」的默认组成部分,直接决定了 “为什么在任意目录输入 ls、nginx 能直接执行”。验证 $PATH 包含 /usr/bin
执行你之前用过的命令:echo $PATH
默认输出(不同系统略有差异,但必然包含 /usr/bin):/usr/bin:/usr/sbin:/bin:/sbin:/home/root/.local/bin
系统会按 $PATH 中的目录顺序,依次查找用户输入的命令;
比如输入 ls,系统先在 /usr/bin 里找,发现 /usr/bin/ls 这个可执行程序,直接执行,不用你输入 /usr/bin/ls。
2. 对比:为什么没放 /usr/bin 的命令需要输完整路径?
Nginx 源码安装后,真实程序在 /usr/local/nginx/sbin/nginx—— 这个目录不在默认 $PATH 里,所以:
没创建软链接前,必须输完整路径 /usr/local/nginx/sbin/nginx 才能执行;
把软链接放到 /usr/bin 后,系统在 $PATH 里找到了 /usr/bin/nginx,直接执行,不用输路径。
三、验证 Nginx 安装成功
1. 查看 Nginx 进程
ps -ef | grep nginxps:Process Status 的缩写,基础命令,用于查询进程状态。
-e:全称 --everyone/--all,显示所有进程(包括系统进程、其他用户进程,不遗漏任何一个)。
-f:全称 --full,以完整格式输出(包含更多进程关键信息,比默认格式详细)。
预期输出(有 1 个主进程 + N 个工作进程):
root 12345 1 0 16:00 ? 00:00:00 nginx: master process nginx
nginx 12346 12345 0 16:00 ? 00:00:00 nginx: worker process
root 12348 12300 0 16:01 pts/0 00:00:00 grep --color=auto nginx
2. 查看 Nginx 监听端口
ss -lntup | grep nginxss:Socket Statistics 的缩写,用于替代传统 netstat,查询系统套接字(网络连接)状态,效率更高。
-l(listen):仅显示 正在监听 的连接(如服务端开放的端口),不显示已建立的连接。
-n(numeric):以 数字形式 显示地址和端口(如直接显示 80 而非 http,127.0.0.1 而非 localhost),避免 DNS 解析,速度更快。
-t(tcp):仅筛选 TCP 协议 的连接(如 HTTP、SSH 等基于 TCP 的服务)。
-u(udp):仅筛选 UDP 协议 的连接(如 DNS、DHCP 等基于 UDP 的服务)。
-p(process):显示每个连接对应的 进程信息(进程 ID PID + 进程名称),需 root 权限(否则可能显示 users:(("unknown",pid=?,fd=?)))。
预期输出(默认监听 80 端口):
tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=12346,fd=6),("nginx",pid=12345,fd=6))
3. 网页访问验证
# 本地访问(验证 Nginx 服务正常响应)
curl localhost # 或 curl 127.0.0.1
预期输出(Nginx 默认欢迎页 HTML 内容):
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</head>
<body>
<h1>Welcome to nginx!</h1>
</body>
</html>
- 若虚拟机有图形界面,可打开浏览器访问
http://localhost; - 若需外部(物理机 / Xshell 所在机器)访问,需开放防火墙 80 端口(见下文补充配置)。
四、关键补充配置(生产环境必需)
1. 开放防火墙 80 端口(允许外部访问)
Nginx 默认监听 80 端口,CentOS 防火墙默认拦截该端口,需手动开放:
# 临时开放 80 端口(立即生效,重启防火墙失效)
firewall-cmd --add-port=80/tcp# 永久开放 80 端口(重启防火墙/系统仍有效)
firewall-cmd --permanent --add-port=80/tcp# 重载防火墙规则(使永久配置生效)
firewall-cmd --reload# 验证端口是否开放
firewall-cmd --list-ports | grep 80/tcp
2. 配置 Nginx 开机自启(systemd 服务)
默认源码安装的 Nginx 无开机自启,需手动配置 systemd 服务:
# 1. 创建 systemd 服务文件
vim /usr/lib/systemd/system/nginx.service
粘贴以下内容(注意 ExecStart 路径与安装路径一致):
[Unit]
Description=Nginx HTTP Server
After=network.target remote-fs.target nss-lookup.target[Service]
Type=forking
# 启动命令(与 Nginx 安装路径一致)
ExecStart=/usr/local/nginx/sbin/nginx
# 停止命令
ExecStop=/usr/local/nginx/sbin/nginx -s stop
# 优雅停止(等待连接结束)
ExecQuit=/usr/local/nginx/sbin/nginx -s quit
# 重载配置
ExecReload=/usr/local/nginx/sbin/nginx -s reload
# 运行用户(需提前创建:useradd -r -s /sbin/nologin nginx)
User=nginx
Group=nginx
PrivateTmp=true[Install]
WantedBy=multi-user.target
# 2. 重新加载 systemd 配置
systemctl daemon-reload# 3. 启用开机自启
systemctl enable nginx.service# 4. 验证开机自启(查看状态)
systemctl status nginx
3. 优化 Nginx 配置文件(conf/nginx.conf)
默认配置文件 /usr/local/nginx/conf/nginx.conf 需根据服务器性能调整:
vim /usr/local/nginx/conf/nginx.conf
关键优化项:
worker_processes auto; # 工作进程数=CPU核心数
worker_connections 10240; # 每个工作进程最大连接数(默认 1024,调高支持高并发)
keepalive_timeout 65; # 长连接超时时间
gzip on; # 启用 gzip 压缩(减少传输带宽)
gzip_types text/plain text/css application/json application/javascript; # 压缩文件类型
修改后重载配置:
nginx -s reload
五、Nginx 常用命令
| 命令用途 | 命令 | ||
|---|---|---|---|
| 启动 Nginx | nginx | ||
| 停止 Nginx(强制) | nginx -s stop | ||
| 优雅停止 Nginx | nginx -s quit | ||
| 重载配置(不重启) | nginx -s reload | ||
| 查看 Nginx 版本 | nginx -v(简单版本)/ nginx -V(编译参数) | ||
| 检查配置文件语法 | nginx -t | ||
| 查看 Nginx 进程 | `ps -ef | grep nginx` | |
| 查看监听端口 | `ss -lntup | grep nginx或netstat -anpt | grep nginx` |
六、常见问题排查
1. 启动失败:端口 80 被占用
# 查找占用 80 端口的进程
ss -lntup | grep :80 或 lsof -i :80
# 停止占用进程(如 httpd):systemctl stop httpd && systemctl disable httpd
# 或修改 Nginx 监听端口(在 nginx.conf 中改 listen 为 8080,需同步开放防火墙 8080 端口)
2. 编译报错:依赖缺失
- 报错
error: C compiler cc is not found→ 安装gcc-c++:dnf install -y gcc-c++ - 报错
error: the HTTP rewrite module requires the PCRE library→ 安装pcre-devel - 报错
error: the HTTP SSL module requires the OpenSSL library→ 安装openssl-devel
3. 外部无法访问:防火墙未开放端口
- 确认防火墙规则:
firewall-cmd --list-ports - 若未显示 80/tcp,重新执行开放命令(见前文 “开放防火墙 80 端口”)
4. 查看 Nginx 错误日志(排查启动 / 运行异常)
tail -f /usr/local/nginx/logs/error.log # 实时查看错误日志
总结
- 源码安装的优势是灵活定制模块(如 HTTPS、TCP 代理),适合生产环境;
- 用户核心操作正确,仅需补充防火墙开放、开机自启、配置优化等生产必需步骤;
- 关键避坑点:编译前补全依赖、启动命令用
./nginx(而非. nginx)、配置开机自启避免重启后服务中断。
Nginx 平滑升级完整笔记
一、平滑升级核心说明
1. 什么是 Nginx 平滑升级?
Nginx 平滑升级(Graceful Upgrade)是指 在不中断现有服务、不影响用户访问的前提下,将 Nginx 从低版本升级到高版本 的过程。核心优势是:
- 升级期间用户无感知(正在下载、访问的连接不会中断);
- 支持快速回滚(若新版本有问题,可立即切换回旧版本);
- 无需重启服务器,适合生产环境(如电商、官网等不能停服的场景)。
2. 核心原理(信号驱动的进程切换)
Nginx 采用「主进程(master)+ 工作进程(worker)」架构,平滑升级依赖 Linux 信号机制实现进程切换:
| 信号 | 作用 |
|---|---|
USR2 | 启动新版本主进程,将旧版本主进程 PID 文件重命名为 nginx.pid.oldbin,新旧主进程共存 |
WINCH | 通知旧版本主进程:平滑关闭旧工作进程(处理完当前连接后退出,不接收新连接) |
QUIT | 退出旧版本主进程(仅在确认新版本正常后执行) |
HUP | 重启工作进程(回滚时使用) |
简单流程:旧主进程 → 启动新主进程 → 旧 worker 进程处理完现有连接退出 → 新 worker 进程承接新连接 → 退出旧主进程。
3. 适用场景与前置条件
适用场景
- 生产环境需要修复低版本漏洞(如安全漏洞、性能缺陷);
- 需使用新版本新增功能(如 HTTP/3 支持、新模块);
- 版本迭代(如 1.26.3 → 1.28.0,同主线稳定版升级)。
前置条件
- 升级前后 Nginx 安装目录一致(本案例为 默认路径 /usr/local/nginx/);
- 新版本编译参数必须与旧版本一致(否则会缺失模块或配置不兼容);
- 磁盘空间充足(编译新版本需临时空间,至少预留 100MB);
- 无配置文件变更(升级期间不要修改
nginx.conf,避免兼容性问题)。
4. 版本选择建议
- 优先升级到 稳定版(Stable Version)(如 1.26.x、1.28.x),避免开发版(Mainline Version);
- 跨大版本升级(如 1.18.x → 1.28.x)前,需查看 Nginx 官方变更日志,确认是否有不兼容配置(如指令废弃、模块变更)。
二、完整平滑升级步骤(默认路径适配版)
前置准备:环境确认与测试准备
1. 确认当前 Nginx 状态(默认路径)
# 查看当前版本(默认安装路径的 Nginx 程序位置)
/usr/local/nginx/sbin/nginx -v
# 预期输出:nginx version: nginx/1.26.3# 查看当前编译参数(关键!新版本需完全一致)
/usr/local/nginx/sbin/nginx -V
# 示例输出:--prefix=/usr/local/nginx --with-http_ssl_module ...(默认路径+原有模块)
# 记录所有编译参数,后续新版本 configure 需完全复制
2. 模拟用户持续访问(验证升级无感知)
为了直观验证升级过程中服务不中断,生成大文件并模拟持续下载:
# 生成 10M 测试文件(存放在 Nginx 默认网站根目录)
dd if=/dev/zero of=/usr/local/nginx/html/test.img bs=1M count=10
# 说明:
dd:核心命令,用于读取、转换并输出数据(常用来创建文件、复制磁盘等);
if=/dev/zero:if(input file)指定输入源,/dev/zero 是系统特殊设备文件,会持续输出空字节(\0);
of=/usr/local/nginx/html/test.img:of(output file)指定输出文件路径和名称,即在 Nginx 的网页根目录下创建 test.img 文件;
bs=1M:bs(block size)指定单次读写的块大小,1M 表示每块 1 兆字节(1024KB);
count=10:count 指定读取 / 写入的块数,这里表示共写入 10 块。# 模拟用户持续下载(限制速率 1K/s,延长下载时间,便于观察升级过程)
wget --limit-rate=1K http://localhost/test.img
# 执行后会持续输出下载进度,升级期间进度不会中断
步骤 1:下载新版本源码包
# 进入源码存放目录(统一管理,推荐 /usr/local/src/)
cd /usr/local/src/# 下载 Nginx 1.28.0 稳定版(官网地址)
wget https://nginx.org/download/nginx-1.28.0.tar.gz# 备用下载地址(国内镜像,速度更快)
# wget http://mirrors.sohu.com/nginx/nginx-1.28.0.tar.gz# 查看下载结果
ls
# 预期输出:nginx-1.26.3 nginx-1.26.3.tar.gz nginx-1.28.0.tar.gz(若之前保留了旧源码)
步骤 2:解压新版本源码包
# 解压 tar.gz 包
tar -zxf nginx-1.28.0.tar.gz# 查看解压结果
ls
# 预期输出:nginx-1.26.3(旧源码,可选保留) nginx-1.28.0(新源码) nginx-1.28.0.tar.gz
步骤 3:配置新版本编译参数(关键!与旧版本一致 + 默认路径)
# 进入新版本源码目录
cd nginx-1.28.0/# 执行 configure 配置(复制旧版本的编译参数,--prefix 保持默认 /usr/local/nginx)
# 以下参数需替换为你执行 nginx -V 输出的实际参数,确保完全一致!
./configure \
--prefix=/usr/local/nginx \ # 默认安装路径,与旧版本一致(核心!)
--user=nginx \ # 旧版本的运行用户(若未指定则省略)
--group=nginx \ # 旧版本的运行组(若未指定则省略)
--with-http_ssl_module \ # 旧版本已启用的模块(按实际补充)
--with-http_v2_module \
--with-http_realip_module \
--with-http_sub_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module# 配置说明:
# 1. --prefix 必须为 /usr/local/nginx(默认路径,确保升级后配置、日志目录不变)
# 2. 所有模块参数需与旧版本 nginx -V 输出完全一致,避免缺失功能
# 3. 若配置报错(如“pcre not found”),补装依赖:dnf install -y pcre-devel openssl-devel zlib-devel
步骤 4:编译新版本(禁止 make install!)
# 编译源码(生成可执行文件,不安装)
make
# 多核心加速编译(推荐,缩短时间):make -j $(nproc)# 编译完成后,查看生成的 objs 目录(存放编译后的可执行文件)
ls
# 预期输出:auto CHANGES conf contrib html LICENSE Makefile man objs README.md SECURITY.md src# 验证新版本可执行文件(编译成功的标志)
objs/nginx -v
# 预期输出:nginx version: nginx/1.28.0# 验证新版本编译参数(与旧版本一致,默认路径+相同模块)
objs/nginx -V
❗ 关键注意:绝对不能执行 make install!make install 会直接覆盖旧版本的配置文件、目录结构,导致服务中断,违背 “平滑升级” 初衷。我们只需替换
nginx可执行文件,无需重新安装。
步骤 5:备份旧版本可执行文件(回滚必备)
# 备份旧版本 nginx 程序(默认路径下的原程序,后缀标注版本号便于识别)
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old.1.26.3# 验证备份结果
ls /usr/local/nginx/sbin/
# 预期输出:nginx.old.1.26.3(旧程序备份)
步骤 6:替换为新版本可执行文件
# 将新版本编译生成的 nginx 程序,复制到默认安装目录的 sbin 下
cp -f objs/nginx /usr/local/nginx/sbin/# 参数说明:-f 强制覆盖(若目标路径有同名文件,直接替换,无需确认)# 验证替换结果(查看新版本是否生效)
/usr/local/nginx/sbin/nginx -v
# 预期输出:nginx version: nginx/1.28.0
步骤 7:发送 USR2 信号,启动新版本主进程
# 查看旧版本主进程 PID 文件(默认路径的 logs 目录)
cat /usr/local/nginx/logs/nginx.pid
# 示例输出:7595(旧 master 进程 ID,记录此数值备用)# 发送 USR2 信号,启动新版本主进程(基于旧 PID 文件)
kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)# 验证效果:
# 1. 日志目录会生成 nginx.pid.oldbin(旧 master 进程的 PID 备份文件)
ls /usr/local/nginx/logs/
# 预期输出:access.log error.log nginx.pid nginx.pid.oldbin# 2. 查看 Nginx 进程(新旧 master 共存,旧 worker 仍在处理连接)
ps auxf | grep nginx
# 预期输出:
# root 7595 0.0 0.1 11112 2452 ? Ss 14:05 0:00 nginx: master process /usr/local/nginx/sbin/nginx (旧 master)
# nginx 7596 0.0 0.2 15388 5140 ? S 14:05 0:00 \_ nginx: worker process (旧 worker)
# root 13814 0.0 0.3 11164 6656 ? S 14:21 0:00 nginx: master process /usr/local/nginx/sbin/nginx (新 master)
# nginx 13815 0.0 0.2 15440 5012 ? S 14:21 0:00 \_ nginx: worker process (新 worker)ps auxf:核心进程查询命令
ps:查看当前系统进程的基础命令;
a:显示所有用户(包括 root)的进程,而非仅当前用户;
u:以 “用户导向” 格式输出,包含进程所属用户、CPU / 内存占用率、启动时间等详细信息;
f:以 “森林(forest)” 形式显示进程树,直观展示进程间的父子关系(比如 nginx 主进程与工作进程的层级)。
x(小写 x)的官方定义是:显示 “无控制终端(tty)的进程”(也就是后台进程、守护进程,比如系统服务 nginx、named、crond 等)
原理说明:USR2 信号会让旧 master 进程启动新版本 master 进程,新 master 进程读取 默认路径下的相同配置文件(/usr/local/nginx/conf/nginx.conf),监听相同端口(端口复用),此时新旧 master 共存:旧 worker 处理现有连接(如之前的 test.img 下载),新 worker 承接所有新连接。
步骤 8:发送 WINCH 信号,关闭旧版本 worker 进程
# 发送 WINCH 信号给旧 master 进程(通过 nginx.pid.oldbin 获取旧 PID)
kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)# 验证效果:旧 worker 进程退出,仅保留新旧 master 和新 worker
ps auxf | grep nginx
# 预期输出:
# root 7595 0.0 0.1 11112 2452 ? Ss 14:05 0:00 nginx: master process /usr/local/nginx/sbin/nginx (旧 master,无 worker)
# root 13814 0.0 0.3 11164 6656 ? S 14:21 0:00 nginx: master process /usr/local/nginx/sbin/nginx (新 master)
# nginx 13815 0.0 0.2 15440 5012 ? S 14:21 0:00 \_ nginx: worker process (新 worker)
原理说明:WINCH 信号通知旧 master 进程 “平滑关闭 worker 进程”—— 旧 worker 会处理完当前正在处理的连接(如持续下载的 test.img),然后优雅退出,不会强制中断用户访问。
步骤 9:验证新版本服务正常(关键测试)
此时新版本已完全承接服务,需从多维度验证功能正常:
# 1. 验证配置文件语法(默认路径的 conf 目录)
/usr/local/nginx/sbin/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# 2. 新终端测试访问(确认新连接能正常响应)
curl http://localhost
# 预期输出:Nginx 默认首页内容(或你的自定义首页)# 3. 验证测试文件下载(确认静态文件服务正常)
curl http://localhost/test.img --output /tmp/test.img
ls -lh /tmp/test.img
# 预期输出:10M 大小的文件(说明服务无异常)# 4. 查看之前的持续下载进程(确认无中断)
# 回到步骤 2 执行 wget 的终端,会看到下载进度持续推进,未中断
步骤 10:退出旧版本主进程(完成升级)
若新版本测试无问题(建议观察 5-10 分钟,确认无报错、无连接中断),发送 QUIT 信号退出旧 master 进程,彻底完成升级:
# 发送 QUIT 信号给旧 master 进程(优雅退出,不影响任何连接)
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)# 验证最终进程状态(仅保留新版本 master 和 worker)
ps auxf | grep nginx
# 预期输出:
# root 13814 0.0 0.3 11164 6656 ? S 14:21 0:00 nginx: master process /usr/local/nginx/sbin/nginx (新 master)
# nginx 13815 0.0 0.2 15440 5012 ? S 14:21 0:00 \_ nginx: worker process (新 worker)# 验证 nginx.pid.oldbin 已消失(旧 master 退出后自动删除)
ls /usr/local/nginx/logs/
# 预期输出:access.log error.log nginx.pid
步骤 11:清理临时文件(可选,节省空间)
# 若确认无需回滚,可删除旧版本程序和新源码包(按需保留)
rm -rf /usr/local/nginx/sbin/nginx.old.1.26.3 # 旧版本程序备份
rm -rf /usr/local/src/nginx-1.28.0 # 新版本源码目录
rm -f /usr/local/src/nginx-1.28.0.tar.gz # 新版本源码包
rm -f /usr/local/nginx/html/test.img # 测试文件
三、关键补充:默认路径下的回滚方案(生产环境必备)
若升级后发现新版本有问题(如日志报错、功能异常、连接中断),需立即回滚到旧版本,步骤如下(默认路径适配):
# 1. 停止新版本 master 进程(通过当前 PID 文件获取新 PID)
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid)# 2. 恢复旧版本可执行文件(从备份还原)
mv /usr/local/nginx/sbin/nginx.old.1.26.3 /usr/local/nginx/sbin/nginx# 3. 启动旧版本 master 进程(通过 nginx.pid.oldbin 获取旧 PID)
kill -HUP $(cat /usr/local/nginx/logs/nginx.pid.oldbin)# 4. 验证回滚结果
/usr/local/nginx/sbin/nginx -v
# 预期输出:nginx version: nginx/1.26.3# 5. 查看进程(旧版本正常运行,承接所有连接)
ps auxf | grep nginx
原理说明:HUP 信号会让旧 master 进程重新加载默认路径下的配置文件,并启动 worker 进程,快速恢复旧版本服务,全程不中断用户连接。回滚后若确认无问题,可执行
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)清理残留的旧 PID 文件。
四、默认路径专属避坑指南
1. 编译参数遗漏默认路径
- 问题:
configure时未指定--prefix=/usr/local/nginx,导致编译后的程序默认指向其他目录; - 解决:升级前执行
usr/local/nginx/sbin/nginx -V,确保--prefix为默认路径,且新版本配置时完全复制该参数。
2. 误删默认目录文件
- 问题:备份旧程序时误删
/usr/local/nginx/conf/或/usr/local/nginx/logs/目录; - 解决:平滑升级仅需操作
sbin/目录下的nginx程序,切勿修改conf/、logs/、html/等目录,这些目录在默认安装后已存储你的配置和数据。
3. 权限问题(默认路径常见)
- 问题:复制新版本程序后,执行
nginx -v提示 “permission denied”; - 解决:默认路径
/usr/local/nginx/sbin/的权限为root:root,确保新版本程序权限正确:bash
chmod 755 /usr/local/nginx/sbin/nginx # 赋予执行权限 chown root:root /usr/local/nginx/sbin/nginx # 保持所有者一致
4. 信号发送失败(PID 文件路径错误)
- 问题:执行
kill -USR2提示 “No such process”; - 解决:默认 PID 文件路径为
/usr/local/nginx/logs/nginx.pid,若之前修改过nginx.conf中的pid指令,需使用修改后的路径(可通过grep "pid" /usr/local/nginx/conf/nginx.conf查看)。
五、总结
默认路径(/usr/local/nginx/)下的 Nginx 平滑升级,核心逻辑与自定义路径一致,仅需确保所有操作都围绕默认目录展开:
- 路径统一:所有命令中的程序、配置、日志路径均使用
/usr/local/nginx/下的对应目录; - 参数一致:新版本编译参数必须与旧版本完全匹配(尤其是
--prefix和模块参数); - 操作谨慎:禁止
make install,仅替换sbin/下的nginx程序,不触碰其他目录。
