Nginx 特性、配置与实战部署
Nginx 特性、配置与实战部署
一、Nginx 概述
Nginx 是一款轻量级的 Web 服务器、反向代理服务器 及 电子邮件(IMAP/POP3)代理服务器,以 内存占用少、并发能力强 著称。在中国大陆,百度、京东、新浪、网易、腾讯、淘宝等头部企业均采用 Nginx 作为核心 Web 服务组件。
二、Nginx 核心特性与优点
(一)核心特性
- 高并发支撑:官方测试可支撑 5 万并发连接,生产环境中常规可达 2-3 万并发,远超传统 Apache 服务器。
- 高效事件模型:基于 epoll(Linux)、kqueue(BSD)等高效事件驱动模型,资源利用率低。
- 多角色支持:可同时作为 Web 服务器、反向代理服务器、负载均衡服务器,且能直接支持 PHP-FPM、uWSGI 等动态服务。
- 高性能设计:采用 C 语言编写,系统资源开销小、CPU 效率高,无 Perlbal 等工具的性能瓶颈。
(二)核心优点
优点分类 | 具体说明 |
性能优势 | - 内存消耗少:3 万并发下,10 个 Nginx 进程仅占用约 150M 内存;- 热部署支持:无需停机即可重载配置文件,保障服务连续性。 |
功能优势 | - 内置健康检查:后端服务器宕机时自动剔除,不影响前端访问;- GZIP 压缩:支持静态资源压缩,节省带宽;- URL 重写:可根据域名、路径分发请求到不同后端;- 模块化设计:核心模块与第三方模块可灵活组合,支持动态编译。 |
成本与稳定性 | - 开源免费:相比 F5 BIG-IP、NetScaler 等硬件负载均衡设备,大幅降低成本;- 稳定性高:作为反向代理时宕机概率极低,适合生产环境长期运行。 |
三、Nginx 功能体系
(一)基本功能
- 静态资源服务:直接处理 HTML、CSS、JS、图片等静态资源,支持缓存打开的文件描述符,提升访问速度。
- 反向代理:支持 HTTP、SMTP、POP3 协议的反向代理,可隐藏后端服务器 IP,提升安全性。
- 负载均衡:通过 upstream 模块实现后端服务器集群的负载分发,支持轮询、IP 哈希、权重等多种算法。
- 动态服务对接:支持 FastCGI(适配 PHP-FPM,用于 LNMP 架构)、uWSGI(适配 Python)等动态服务协议。
- 基础过滤与处理:内置 ZIP 压缩、SSI 解析、图像大小调整等过滤器模块。
- SSL 支持:集成 http_ssl_module,可配置 HTTPS 协议,保障数据传输安全。
(二)扩展功能
- 虚拟主机:支持基于域名(server_name)和 IP 的多虚拟主机,实现一台服务器部署多个站点。
- 连接优化:支持 keepalive 长连接,减少 TCP 握手开销;开启 tcp_nodelay 优化长连接数据传输。
- 访问控制:基于 IP 地址、用户身份(如 Basic Auth)限制访问,保障站点安全。
- 流量控制:支持速率限制(limit_rate)和并发数限制(limit_conn),防止恶意请求压垮服务器。
- 日志定制:支持自定义访问日志格式,可使用日志缓冲区提升存储性能,便于后续日志分析。
四、Nginx 模块分类
Nginx 的功能由模块支撑,模块按来源分为三类:
模块类型 | 包含模块示例 | 功能说明 |
核心模块 | HTTP 模块、EVENT 模块、MAIL 模块 | Nginx 运行的基础,默认编译进程序,负责协议解析、事件驱动等核心逻辑。 |
基本模块 | HTTP Access 模块、HTTP FastCGI 模块、HTTP Proxy 模块、HTTP Rewrite 模块 | 扩展核心功能,如访问控制、FastCGI 对接、反向代理、URL 重写等。 |
第三方模块 | HTTP Upstream 模块、Request Hash 模块、Notice 模块、HTTP Access Key 模块 | 由社区或用户开发,满足特定场景需求(如自定义负载均衡算法、访问密钥验证)。 |
五、Nginx 工作原理
(一)进程架构
Nginx 采用 Master-Worker 多进程模型,启动后包含两类进程:
- Master 进程:仅 1 个,不处理客户端请求,负责管理 Worker 进程:
-
- 读取并验证配置文件;
-
- fork(创建)Worker 进程;
-
- 接收信号(如重载配置、停止服务)并分发给 Worker 进程。
2.Worker 进程:多个(数量由 worker_processes 配置),核心职责是处理客户端请求,每个 Worker 进程独立运行,通过事件驱动模型处理多个请求。
(二)关键技术点
- 惊群问题与互斥锁
-
- 惊群问题:当一个客户端连接到来时,所有 Worker 进程都会收到通知并尝试抢占连接,导致资源浪费。
-
- 解决方案:开启 accept_mutex(互斥锁),同一时刻仅允许一个 Worker 进程抢占连接,避免竞争。
2.连接池机制
-
- 每个 Worker 进程有独立的连接池,大小由 worker_connections 配置,存储 ngx_connection_t 结构(非真实连接)。
-
- 连接池通过空闲链表(free_connections)管理,获取连接时从链表取,释放后放回,提升资源复用效率。
3.最大并发数计算
-
- 静态资源服务:最大并发数 = worker_processes × worker_connections;
-
- 反向代理服务:最大并发数 =(worker_processes × worker_connections)/ 2(每个请求需占用 “客户端 - nginx” 和 “nginx - 后端” 两个连接)。
六、Nginx 配置文件详解
(一)配置文件结构
Nginx 主配置文件默认路径为 /usr/local/nginx/conf/nginx.conf,结构分为 4 个层级,按生效范围从大到小为:
main # 全局配置段(影响所有进程)├─ events # 事件模型配置段(影响 Worker 进程的事件处理)└─ http # HTTP 协议配置段(影响所有 HTTP 服务)├─ upstream # 负载均衡集群配置(定义后端服务器组)└─ server # 虚拟主机配置(对应一个站点)└─ location # 请求匹配配置(按 URI 分发请求)
(二)核心配置参数
1. main 全局配置段
参数 | 格式 | 功能说明 |
daemon | `daemon {on off};` | |
master_process | `master_process {on off};` | |
error_log | error_log 路径 级别; | 错误日志配置,级别包括 debug、info、warn、error、crit(生产环境推荐 error 或 warn)。 |
worker_processes | worker_processes n; | Worker 进程数量,建议设为 CPU 核心数(或核心数 - 1),避免上下文切换。 |
worker_cpu_affinity | worker_cpu_affinity cpumask ...; | 将 Worker 进程绑定到指定 CPU 核心(如 0001 0010 表示第 1、2 核心),减少缓存刷新。 |
worker_rlimit_nofile | worker_rlimit_nofile number; | 所有 Worker 进程最大可打开文件数(默认 1024,生产环境建议设为 65535)。 |
pid | pid /path/to/pid_file; | 指定 Master 进程 PID 文件路径(如 /var/run/nginx.pid)。 |
2. events 事件配置段
参数 | 格式 | 功能说明 |
accept_mutex | `accept_mutex {on off};` | |
use | `use [epollrtsig | |
worker_connections | worker_connections 1024; | 每个 Worker 进程最大连接数(生产环境建议设为 10240 以上)。 |
3. http 协议配置段
http 段是最核心的配置区域,包含 upstream、server、location 等子段,基础配置示例:
http {include mime.types; # 引入 MIME 类型映射文件default_type application/octet-stream; # 默认 MIME 类型# 日志配置log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log /var/log/nginx/access.log main; # 访问日志路径与格式# 连接优化sendfile on; # 启用 sendfile 高效传输文件tcp_nopush on; # 配合 sendfile 使用,提升传输效率keepalive_timeout 65; # 长连接超时时间(默认 65s)# 负载均衡集群(upstream 段)upstream backend_servers {server 192.168.100.30:80 weight=1; # 后端服务器 1,权重 1server 192.168.100.40:80 weight=2; # 后端服务器 2,权重 2(接收更多请求)server 192.168.100.50:80 backup; # 备份服务器(主服务器全部宕机时启用)}# 虚拟主机(server 段)server {listen 80; # 监听端口(HTTP 默认 80)server_name www.example.com; # 虚拟主机域名(可配置多个,用空格分隔)# 请求匹配(location 段)location / {root /var/www/html; # 站点根目录index index.html index.htm; # 默认索引文件proxy_pass http://backend_servers; # 反向代理到 upstream 集群}}}
4. location 配置(请求匹配)
location 用于按 URI 匹配请求,格式为 location [修饰符] pattern { ... },核心是 修饰符与优先级。
修饰符 | 作用 | 优先级 |
= | 精确匹配 URI(如 location = /abc 仅匹配 /abc,不匹配 /abc/123) | 1(最高) |
^~ | 前缀匹配,匹配成功后停止搜索其他模式(不支持正则) | 3 |
~ | 正则匹配,区分大小写(如 ~ /ABC 不匹配 /abc) | 4 |
~* | 正则匹配,不区分大小写(如 ~* /ABC 匹配 /abc) | 4 |
无修饰符 | 前缀匹配,匹配成功后继续搜索更精确的模式 | 5(最低) |
优先级验证示例:
# 1. 精确匹配(优先级最高)location = /abc { echo "=1"; }# 2. 前缀匹配(优先级次高)location ^~ /abc { echo "^~2"; }# 3. 正则匹配(区分大小写,优先级低于 ^~)location ~ /abc { echo "~3"; }# 4. 正则匹配(不区分大小写,优先级与 ~ 按配置顺序)location ~* /abc$ { echo "~*4"; }# 5. 无修饰符前缀匹配(优先级最低)location /abc { echo "null5"; }
- 访问 http://192.168.100.10/abc,输出 =1(精确匹配生效);
- 删除 = 规则后,输出 ^~2(^~ 生效);
- 删除 ^~ 规则后,输出 ~3(~ 比 ~* 先配置,优先生效);
- 删除正则规则后,输出 null5(无修饰符生效)。
5. FastCGI 配置(对接 PHP-FPM)
在 LNMP 架构中,Nginx 通过 FastCGI 转发 PHP 请求到 PHP-FPM,核心配置如下:
location ~ \.php$ {root /var/www/html; # PHP 站点根目录(需与 PHP-FPM 一致)fastcgi_pass 192.168.100.30:9000; # PHP-FPM 地址(IP:端口)fastcgi_index index.php; # 默认 PHP 索引文件# 传递 PHP 脚本路径(固定格式,确保 PHP 能找到源码)fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params; # 引入 FastCGI 通用参数(如 PATH_INFO)}
(三)常用配置文件说明
配置文件 | 路径 | 功能 |
nginx.conf | /usr/local/nginx/conf/nginx.conf | 主配置文件,包含全局、events、http 等核心配置。 |
mime.types | /usr/local/nginx/conf/mime.types | MIME 类型映射表,定义文件扩展名与 Content-Type 的对应关系(如 .html 对应 text/html)。 |
fastcgi.conf | /usr/local/nginx/conf/fastcgi.conf | FastCGI 专用配置,包含 PHP 运行所需的环境变量。 |
proxy.conf | /usr/local/nginx/conf/proxy.conf | 反向代理专用配置,如代理超时、请求头设置等。 |
sites.conf | /usr/local/nginx/conf/sites.conf | 虚拟主机配置(可选),集中管理多个 server 段,通过 include 引入主配置。 |
七、Nginx 部署实战
(一)单节点 Nginx 部署(CentOS 7)
1. 环境准备
# 关闭防火墙与 SELinuxsystemctl stop firewalld && systemctl disable firewalldsetenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config# 安装依赖包与开发工具yum -y groupinstall "Development Tools"yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make zlib-devel wget lrzsz# 创建 Nginx 专用用户(无登录权限)useradd -r -M -s /sbin/nologin nginx# 创建日志目录并授权mkdir -p /var/log/nginxchown -R nginx:nginx /var/log/nginx
2. 源码编译安装
# 下载 Nginx 源码包(以 1.24.0 版本为例)wget http://nginx.org/download/nginx-1.24.0.tar.gz# 解压源码包tar -xzvf nginx-1.24.0.tar.gz -C /usr/local/# 编译配置(启用 SSL、静态压缩、状态监控等模块)cd /usr/local/nginx-1.24.0/./configure --prefix=/usr/local/nginx \--user=nginx \--group=nginx \--with-debug \--with-http_ssl_module \--with-http_realip_module \--with-http_image_filter_module \--with-http_gunzip_module \--with-http_gzip_static_module \--with-http_stub_status_module \--http-log-path=/var/log/nginx/access.log \--error-log-path=/var/log/nginx/error.log# 编译与安装make && make install# 配置环境变量(全局可调用 nginx 命令)echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.shsource /etc/profile.d/nginx.sh
3. 服务管理
# 验证配置文件语法nginx -t#启动 Nginx
nginx查看 Nginx 进程与端口(确认 80 端口已监听)
ps -ef | grep nginxss -anlt | grep 80重载配置文件(修改配置后无需停机)
nginx -s reload停止 Nginx(优雅停止,处理完当前请求后退出)
nginx -s quit强制停止 Nginx(紧急情况使用)
nginx -s stop
(二)分布式 LNMP 架构部署(三台服务器)
基于“Nginx 单独部署+MySQL 单独部署+PHP 单独部署”的架构,服务器信息如下:
- Nginx 服务器:192.168.100.10(接收请求,处理静态资源,转发 PHP 请求)
- MySQL 服务器:192.168.100.20(存储数据,如 WordPress 数据库)
- PHP 服务器:192.168.100.30(运行 PHP-FPM,处理动态请求,连接 MySQL)
1. 前置准备(所有服务器)
# 关闭防火墙与 SELinux(同单节点部署)systemctl stop firewalld && systemctl disable firewalldsetenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config# 配置 hosts 解析(便于跨服务器访问,可选)echo "192.168.100.10 nginx-server" >> /etc/hostsecho "192.168.100.20 mysql-server" >> /etc/hostsecho "192.168.100.30 php-server" >> /etc/hosts
2. MySQL 服务器(192.168.100.20)配置
vim /etc/man_db.conf
添加
MANDATORY_MANPATH /usr/local/mysql/manvim /etc/ld.so.conf.d/mysql.conf
添加
/usr/local/mysql/lib
3. PHP 服务器(192.168.100.30)配置
# 安装 PHP 7.0 与依赖(启用 Remi 源)yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpmyum -y install yum-utilsyum-config-manager --enable remi-php70yum -y install php php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mbstring php-curl php-xml php-pear php-bcmath php-json php-redis# 配置 PHP-FPM(允许 Nginx 服务器访问)vim /etc/php-fpm.d/www.conf# 修改以下参数:listen = 0.0.0.0:9000 # 监听全网(或仅 Nginx 服务器 IP:192.168.100.10)listen.allowed_clients = 192.168.100.10 # 仅允许 Nginx 服务器连接# 创建 PHP 站点目录并部署测试文件mkdir -p /var/www/htmlvim /var/www/html/index.php# 写入测试内容:<?phpphpinfo();?># 授权目录权限(与 PHP-FPM 运行用户一致,默认 apache)chown -R apache:apache /var/www/html/# 启动 PHP-FPM 并设置开机自启systemctl start php-fpm && systemctl enable php-fpmss -anlt | grep 9000 # 确认 9000 端口已监听
4. Nginx 服务器(192.168.100.10)配置
# 部署单节点 Nginx(参考本章“单节点 Nginx 部署”步骤)# 修改 Nginx 配置文件,转发 PHP 请求到 PHP 服务器vim /usr/local/nginx/conf/nginx.conf# 调整 http 段中的 server 配置:server {listen 80;server_name www.example.com; # 站点域名(或 Nginx 服务器 IP)# 处理静态资源location / {root /var/www/html; # 静态资源目录(可与 PHP 服务器目录一致,或单独存放)index index.php index.html index.htm; # 优先解析 index.php}# 转发 PHP 请求到 PHP 服务器location ~ \.php$ {root /var/www/html; # 必须与 PHP 服务器的站点目录一致fastcgi_pass 192.168.100.30:9000; # PHP 服务器 IP:PHP-FPM 端口fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name; # 传递 PHP 脚本路径include fastcgi_params;}}# 验证配置并重启 Nginxnginx -tnginx -s reload# 测试 PHP 解析(浏览器访问 Nginx 服务器 IP)# 若显示 PHP 信息页面,说明 LNMP 架构部署成功
八、Nginx 平滑升级与模块添加
平滑升级指 在不中断服务的情况下升级 Nginx 版本或添加新模块,核心是利用 Nginx 的 Master-Worker 模型,逐步替换旧进程。
(一)平滑升级步骤(以添加 echo-nginx-module 为例)
1. 准备工作
# 1. 获取当前 Nginx 的编译参数(必须保留,避免丢失原有模块)nginx -V # 输出示例:--prefix=/usr/local/nginx --user=nginx ...# 2. 下载新模块(以 echo 模块为例,用于输出自定义内容)wget https://github.com/openresty/echo-nginx-module/archive/refs/heads/master.zip -O echo-nginx-module-master.zipunzip echo-nginx-module-master.zip -d /root/ # 解压到 /root/ 目录# 3. 下载与当前版本一致的 Nginx 源码包(避免版本冲突)wget http://nginx.org/download/nginx-1.24.0.tar.gztar -xzvf nginx-1.24.0.tar.gz
2. 重新编译(添加新模块)
cd nginx-1.24.0/# 复制原有编译参数,并添加 --add-module 指向新模块路径./configure --prefix=/usr/local/nginx \--user=nginx \--group=nginx \--with-debug \--with-http_ssl_module \--with-http_realip_module \--with-http_image_filter_module \--with-http_gunzip_module \--with-http_gzip_static_module \--with-http_stub_status_module \--http-log-path=/var/log/nginx/access.log \--error-log-path=/var/log/nginx/error.log \--add-module=/root/echo-nginx-module-master # 新增模块路径# 编译(仅 make,不执行 make install,避免覆盖旧程序)make
3. 替换旧程序并平滑重启
# 1. 备份旧 Nginx 程序(防止升级失败回滚)cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old# 2. 停止旧 Worker 进程(Master 进程保留)kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` # 启动新 Master 进程(使用新程序)kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin` # 优雅停止旧 Worker 进程# 3. 验证新程序(查看模块是否添加成功)nginx -V # 输出中应包含 --add-module=/root/echo-nginx-module-master# 4. 测试新模块(修改 Nginx 配置)vim /usr/local/nginx/conf/nginx.confserver {listen 80;server_name localhost;location / {echo "hello"; # 使用 echo 模块输出内容}}# 5. 重载配置并测试nginx -s reloadcurl http://192.168.100.10 # 输出 "hello",说明模块生效
4. 回滚方案(若升级失败)
# 1. 启动旧 Worker 进程kill -HUP `cat /usr/local/nginx/logs/nginx.pid.oldbin`# 2. 停止新 Master 进程kill -QUIT `cat /usr/local/nginx/logs/nginx.pid`# 3. 恢复旧程序mv /usr/local/nginx/sbin/nginx.old /usr/local/nginx/sbin/nginx# 4. 重启 Nginxnginx
九、总结
Nginx 凭借 高性能、高稳定性、低资源消耗 的优势,成为当前 Web 服务领域的主流选择。本文从 Nginx 的核心特性、工作原理、配置文件、部署实战到平滑升级,全面覆盖了 Nginx 的关键知识点:
- 功能定位:Web 服务器、反向代理、负载均衡是 Nginx 的核心应用场景;
- 配置核心:理解 main-events-http-server-location 的层级结构,掌握 location 修饰符优先级与 FastCGI 配置;
- 实战重点:分布式 LNMP 架构需关注跨服务器通信(如 Nginx 转发 PHP 请求、PHP 连接 MySQL),平滑升级需保留原有编译参数,避免服务中断;
- 优化方向:根据服务器 CPU 核心数调整 worker_processes,开启 accept_mutex 解决惊群问题,通过 gzip 与 keepalive 优化性能。
掌握这些内容后,可基于 Nginx 搭建高可用、高性能的 Web 服务,满足中小型乃至大型站点的需求。