简介Nginx 1.22.0 Linux 版本的源码压缩包面向需要在 Linux 上自建反向代理、静态资源服务或学习高性能服务器设计的运维与开发人员。整个 7z 压缩包仅 714KB却包含 403 个文件以 207 个 C 源文件和 98 个头文件为主体覆盖 HTTP 核心模块、事件驱动、代理转发等核心实现另附 14 个 conf 配置样例、7 个 make 构建脚本以及 configure 脚本、更新记录、许可证等齐全的构建与说明文件还收录了 Linux、FreeBSD、Solaris、Windows 等平台的适配代码方便对照理解跨平台编译逻辑。该版本延续了 Nginx 轻量、高并发的优势解压后即可按常规方式配置编译适合用于生产环境评估或二次定制开发。已有 3326 人学习下载解压后既能获得可编译的完整工程也能通过阅读源码、配置模板和平台适配代码快速掌握模块划分、构建流程与反向代理的底层实现是运维人员排查问题和开发者研究 Nginx 内部机制时的实用参考。1. 解压安装 Nginx 1.22.0绕开包管理器把版本控制权拿回来拿到一台内网机器上不了公网软件源或者交付现场要求锁死版本你会发现系统自带的 Nginx 要么没有要么版本号和你本地测的不一致。Nginx 1.22.0 Linux 版解压安装说白了就是不用 yum/apt而是把官方归档下载到服务器上解压、configure、make、make install把一套完全可控的 Nginx 装进指定目录。它的价值在三点版本自己定、模块自己选、安装目录自己划。适合离线环境交付、同一台机器多版本共存、以及需要往二进制里塞自定义模块的场景。这篇笔记按一条完整链路讲依赖、编译、参数、配置、排错、托管与升级照着走能落地。2. 解压安装步骤依赖、下载校验、configure 与 make install 全命令解压安装的核心难点不在 tar 那一步而在 configure。configure 决定这个 Nginx 1.22.0 装完之后有哪些模块、运行时依赖哪些动态库、日志写到哪、pid 文件放哪。configure 跑不过后面 make 和 make install 都是白搭。所以顺序不能乱先补依赖再下载归档最后编译安装。2.1 编译依赖三件套PCRE、OpenSSL、zlib 一次装齐源码编译 Nginx 1.22.0 至少需要编译器、make 工具和三个开发库。Debian/Ubuntu 系和 RHEL/CentOS 系的包名不一样先列出两种写法# Debian/Ubuntu 系 apt-get update apt-get install -y build-essential libpcre3-dev libssl-dev zlib1g-dev # RHEL/CentOS 系 yum install -y gcc make pcre-devel openssl-devel zlib-develPCRE 负责正则表达式Nginx 的 rewrite 模块和 location 正则匹配都靠它OpenSSL 负责 HTTPS 和 TLS 相关能力zlib 负责 gzip 压缩。这三个开发库缺任何一个configure 都会在中途停下。build-essential 或 gcc/make 提供编译器没有它 configure 连第一步的测试编译都跑不了。如果机器是内网隔离的提前把这三个 rpm 或 deb 包拷进去用离线方式安装方法一样。提示装完后可以用dpkg -l | grep pcre或rpm -qa | grep pcre确认开发包确实存在。只装了运行时库没装 -dev/-devel 包configure 依然会报找不到头文件。2.2 下载归档并校验解压前先做一次 sha256 核对Nginx 1.22.0 的源码包在官网下载页里可以找到常见路径是 nginx.org 的 download 目录下的nginx-1.22.0.tar.gz。下载时顺手把配套的校验文件也拉下来不要解压完才想起验证。mkdir -p /opt/src cd /opt/src wget https://nginx.org/download/nginx-1.22.0.tar.gz wget https://nginx.org/download/nginx-1.22.0.tar.gz.sha256 sha256sum -c nginx-1.22.0.tar.gz.sha256 tar -zxvf nginx-1.22.0.tar.gz cd nginx-1.22.0sha256sum -c会拿文件实际算出来的哈希值和官方给出的比对输出OK才说明下载过程没被破坏。这一步在公网下载时容易被忽略但它在交付场景里是个习惯问题镜像源可能滞后也可能出现坏块。解压之后不要急着改目录名直接进nginx-1.22.0编译configure 脚本对当前目录有路径假设。2.3 configure、make、make install一条命令链讲清路径规划进入源码目录后第一件事是规划安装路径。我一般会按下面这组参数来既满足独立部署又方便后续用 systemd 托管./configure \ --prefix/usr/local/nginx \ --sbin-path/usr/local/nginx/sbin/nginx \ --conf-path/usr/local/nginx/conf/nginx.conf \ --pid-path/var/run/nginx.pid \ --http-log-path/var/log/nginx/access.log \ --error-log-path/var/log/nginx/error.log \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-threads这里每个参数都有讲究。--prefix决定安装根后面没显式指定的路径都会以它为基准--sbin-path固定可执行文件位置避免前缀变了二进制找不到--pid-path放在/var/run下是因为后续用kill信号做平滑升级时系统默认去/var/run找 pid 文件日志路径单独拎到/var/log/nginx和程序目录分开日志轮转和排查都干净。模块方面with-http_ssl_module让 Nginx 1.22.0 具备 HTTPS 能力with-http_v2_module开启 HTTP/2with-http_stub_status_module暴露连接状态页with-threads开启线程池。如果业务明确用不到 rewrite可以追加--without-http_rewrite_module减少依赖但绝大多数场景不建议动。configure 跑完后最后几行会打印Configuration summary逐条列出将安装的路径和启用的模块。养成读这个输出的习惯比装完再nginx -V回查更省事。接下来编译make -j $(nproc) make install-j $(nproc)让 make 按 CPU 核数并行编译四核机器能明显加快速度。如果 make 中途报错先看完整输出不要只盯着最后一行Error。另外注意如果日志路径配到了/var/log/nginxmake install 不会帮你创建这个目录需要手动mkdir -p /var/log/nginx并保证 nginx 进程有写权限常见做法是建一个专用用户或者用 root 启动后降权。安装完成后看一眼关键文件ls -l /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx -V-V输出里包含编译时的 configure 参数和 OpenSSL 版本号确认无误后这套 Nginx 1.22.0 才算真正装好。3. configure 参数与第一份配置把 1.22.0 裁剪到够用装完只是起点。手编 Nginx 的好处是你可以把它裁剪得和系统包管理器的默认行为完全不同代价是你得知道每个参数在干什么。这一章给出常用参数速查表和一份能立刻跑起来的最小配置。3.1 常用 configure 参数速查加什么、去掉什么、什么时候动参数作用什么时候需要动--prefix安装根目录多版本共存、非 root 目录部署时必改--with-http_ssl_module启用 HTTPS要上证书就开没开后面配 listen 443 会直接报错--with-http_v2_module启用 HTTP/2有 HTTPS 且想上 HTTP/2 时开--with-http_stub_status_module输出连接状态页需要监控连接数、请求数时开--with-http_realip_module取真实客户端 IP前面挂了负载均衡或 CDN 时开--with-stream四层 TCP/UDP 转发做端口代理、数据库代理时开--without-http_rewrite_module禁用 rewrite确定不用 URL 重写时开能省掉 PCRE 依赖--with-cc-opt/--with-ld-opt传递编译/链接参数链接第三方库或指定头文件路径时用裁剪思路有一个原则业务用不到的功能一律不加。比如一台只做静态文件服务的机器ssl 模块和 stream 模块都不需要编译出来的二进制更小出问题的面也更窄。但 stub_status 我建议保留排查连接数时没有这个模块只能靠猜。configure 参数一旦定下来建议存到文件里比如/opt/src/nginx-1.22.0.configure.args后续升级或复盘时就有一条明确的记录。3.2 最小 nginx.conf装完后 10 分钟内能启动的配置make install 完成之后/usr/local/nginx/conf/nginx.conf是一份带大量注释的示例配置。新手可以先不读它直接用下面这份最小可运行配置worker_processes 1; error_log logs/error.log info; pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent; access_log logs/access.log main; sendfile on; server { listen 80; server_name localhost; location / { root html; index index.html; } } }这份配置里error_log和pid用的是相对路径相对的是--prefix指定的目录也就是/usr/local/nginx/logs/。worker_processes 1在低配虚机上足够压力上来后再改auto或固定为核数。mime.types是 make install 自动生成的它会告诉浏览器.html对应text/html、.js对应application/javascript不 include 的话所有文件都会按default_type返回。sendfile on是静态文件服务的关键参数减少内核态和用户态之间的数据拷贝对性能影响明显。3.3 启动与验证从 -t 到 curl 再到日志链路配置写完之后启动之前先验配置/usr/local/nginx/sbin/nginx -t /usr/local/nginx/sbin/nginx curl -I http://127.0.0.1/ curl -s http://127.0.0.1/ | head -20nginx -t只做语法检查不启动进程输出syntax is ok就说明配置没问题。启动后curl -I看响应头重点确认Server: nginx/1.22.0这一行版本号对得上说明跑的就是我们刚编译的二进制。curl首页内容能拿到说明目录里的index.html被正确解析。最后手动访问一个不存在的路径然后去看logs/error.logcurl -s http://127.0.0.1/not-exist tail -f /usr/local/nginx/logs/error.log如果 error.log 里出现open() /usr/local/nginx/html/not-exist failed (2: No such file or directory)的记录说明日志链路、root 路径、worker 进程权限这三件事都是通的。4. 解压安装避坑记录5 个翻车点与对应排查思路手编 Nginx 1.22.0 这条链路里坑基本都集中在 configure、make、启动这三段。下面 5 个现象是我在真实环境里反复撞过的每条按现象、原因、解决来写遇到可以直接对照。4.1 configure 报错 C compiler cc is not found先查 gcc 而不是查 configure现象执行./configure后立刻中断屏幕提示C compiler cc is not found。原因系统里没有安装 gcc或者 gcc 装了但不在当前 shell 的 PATH 里。很多最小化安装的 Linux 镜像默认不带编译套件这是最常见的第一道坎。解决先执行which gcc gcc --version没有输出就装包。Debian/Ubuntu 用apt-get install -y build-essentialRHEL/CentOS 用yum install -y gcc make。装完重新跑 configure不需要清理configure 会重新检测。4.2 configure 报错 HTTP rewrite module requires the PCRE library现象configure 进行到一半输出the HTTP rewrite module requires the PCRE library后退出。原因系统里没有 PCRE 的开发库。只有运行时库libpcre.so不够configure 需要的是头文件pcre.h这由-dev或-devel包提供。如果之前用yum install pcre而不是pcre-devel就会卡在这里。解决按第 2.1 节补装libpcre3-devDebian/Ubuntu或pcre-develRHEL/CentOS。极端情况下如果必须绕过这个依赖可以加--without-http_rewrite_module重新 configure但代价是 location 正则匹配能力也没了非必要别这么做。4.3 make 卡死或报 Error先看磁盘、TMPDIR 和权限别急着重跑现象make 执行到一半中断最后一行是Error 1或Error 2往上翻能看到具体文件名但也可能只看到一堆编译命令。原因最常见三个磁盘满、/tmp 空间不足、configure 指定的 prefix 目录没有写权限。编译过程会生成大量临时对象文件/tmp 小的机器很容易爆掉。解决先df -h /tmp和df -h /usr/local确认剩余空间再确认当前用户对 prefix 目录有写权限。如果 /tmp 太小给 make 指定大目录make TMPDIR/var/tmp -j $(nproc)。还有一种情况是解压目录的 owner 是别人chmod -R uw或换一个干净的目录重新解压。4.4 启动时报 error while loading shared libraries动态库路径不一致现象执行/usr/local/nginx/sbin/nginx时shell 提示error while loading shared libraries: libpcre.so.1: cannot open shared object file。原因编译时能找到动态库运行时系统加载器找不到。常见于把编译好的目录拷到另一台机器上运行或者 PCRE 库放在/usr/local/lib但系统默认不搜索这个路径。解决先ldconfig -p | grep pcre看库里有没有这个 so 文件。没有的话找到它所在路径比如/usr/local/lib然后写一个 loader 配置echo /usr/local/lib /etc/ld.so.conf.d/nginx-libs.conf ldconfig这个坑最典型的表现是编译机正常、运行机报错所以跨机器拷贝二进制之前最好在目标机器上先跑一遍nginx -V确认动态库都能解析。4.5 端口被占nginx: [emerg] bind() to 0.0.0.0:80 failed现象启动时 error.log 里出现bind() to 0.0.0.0:80 failed (98: Address already in use)进程起不来。原因80 端口被 Apache、其他 Nginx 实例或者某个自启动服务占用。手编场景里还有一种是同一台机器上一个 Nginx 还没停又启动了第二个。解决先看谁占着端口ss -lntp | grep :80确认占用进程后要么停掉它要么改配置文件里的listen端口。如果是自己起了两个 Nginx用/usr/local/nginx/sbin/nginx -s quit停掉旧实例再启动新的。5. 把 Nginx 1.22.0 接入 systemd开机自启与平滑升级技巧解压安装的一大短板是它默认不带系统的服务管理能力重启机器后 Nginx 不会自己起来。解决办法是手动写一个 systemd service 文件把进程托管给系统。这也是手编安装的收尾动作做完这套整台机器的 Nginx 才算是真正交付。5.1 systemd service 模板把 1.22.0 托管给进程管理器在/etc/systemd/system/nginx.service下写入下面的内容注意 PIDFile 和 configure 里的--pid-path保持一致[Unit] DescriptionNginx 1.22.0 Web Server Afternetwork.target [Service] Typeforking PIDFile/var/run/nginx.pid ExecStartPre/usr/local/nginx/sbin/nginx -t ExecStart/usr/local/nginx/sbin/nginx ExecReload/usr/local/nginx/sbin/nginx -s reload ExecStop/usr/local/nginx/sbin/nginx -s quit PrivateTmptrue [Install] WantedBymulti-user.targetTypeforking是因为 Nginx 启动时 master 进程会 fork 出 worker 进程systemd 需要靠 PIDFile 来识别主进程。ExecStartPre里先跑nginx -t配置写错了 systemd 会在启动前拦截而不是启动后立刻死掉。配好后执行systemctl daemon-reload systemctl enable nginx systemctl start nginx systemctl status nginxstatus输出里能看到Active: active (running)并且日志里出现nginx/1.22.0字样。以后重载配置用systemctl reload nginx停止用systemctl stop nginx不用再记 Nginx 自己的信号序列不过 Nginx 的-s reload信号依然可用两者等价。5.2 二进制平滑升级USR2 信号与回滚姿势解压安装的另一个好处是升级路径清晰。Nginx 1.22.0 属于 stable 分支后续同分支会有补丁版本发布。升级时不中断服务的方式是保留旧二进制用 USR2 信号让新旧 master 并行再逐个切换 worker。# 1. 备份旧二进制和 configure 参数 cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old cp /opt/src/nginx-1.22.0.configure.args /opt/src/nginx.upgrade.args # 2. 用新源码重新 configure、make但不要 make install tar -zxvf nginx-1.2x.x.tar.gz cd nginx-1.2x.x ./configure $(cat /opt/src/nginx.upgrade.args) make # 3. 替换二进制 cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.current cp ./objs/nginx /usr/local/nginx/sbin/nginx # 4. 发 USR2 信号拉起新 master kill -USR2 $(cat /var/run/nginx.pid) # 5. 确认新 master 正常后关闭旧 worker sleep 1 kill -QUIT $(cat /var/run/nginx.pid.oldbin)升级前先跑新二进制的nginx -t确认配置兼容。如果新进程起不来系统会保留nginx.pid.oldbin这个旧 pid 文件用旧的nginx.old替换回去再发信号就能回滚。这套流程的好处是连接不断适合线上跑着真实流量的时候操作。我自己的习惯是每次升级都留一份nginx -V输出和旧二进制一是回滚有后悔药二是半年后排查“当时编了哪些模块”不用靠猜。希望帮到你。本文还有配套的精品资源点击获取