Nginx 服务器技术手册
CentOS 7 版
文章目录
- [Nginx 服务器技术手册](#Nginx 服务器技术手册)
- [1. Nginx 简介](#1. Nginx 简介)
-
- [1.1 什么是 Nginx](#1.1 什么是 Nginx)
- [1.2 Nginx 的特点](#1.2 Nginx 的特点)
- [1.3 Nginx 与 Apache 的对比](#1.3 Nginx 与 Apache 的对比)
- [1.4 Nginx 主要应用场景](#1.4 Nginx 主要应用场景)
- [2. 安装与初始化配置](#2. 安装与初始化配置)
-
- [2.1 安装方式选择](#2.1 安装方式选择)
-
- [2.1.1 官方源安装(推荐)](#2.1.1 官方源安装(推荐))
- [2.1.2 源码编译安装](#2.1.2 源码编译安装)
- [2.2 目录结构](#2.2 目录结构)
- [2.3 防火墙配置](#2.3 防火墙配置)
- [2.4 基本操作命令](#2.4 基本操作命令)
- [3. 核心配置文件详解](#3. 核心配置文件详解)
-
- [3.1 配置文件结构](#3.1 配置文件结构)
- [3.2 全局配置 (main)](#3.2 全局配置 (main))
- [3.3 事件配置 (events)](#3.3 事件配置 (events))
- [3.4 HTTP 配置 (http)](#3.4 HTTP 配置 (http))
- [3.5 配置文件常用指令说明](#3.5 配置文件常用指令说明)
- [4. 虚拟主机配置实践](#4. 虚拟主机配置实践)
-
- [4.1 基于域名的虚拟主机](#4.1 基于域名的虚拟主机)
-
- [4.1.1 创建目录结构](#4.1.1 创建目录结构)
- [4.1.2 配置虚拟主机](#4.1.2 配置虚拟主机)
- [4.1.3 测试配置](#4.1.3 测试配置)
- [4.2 基于端口的虚拟主机](#4.2 基于端口的虚拟主机)
- [4.3 基于 IP 的虚拟主机](#4.3 基于 IP 的虚拟主机)
- [4.4 默认虚拟主机](#4.4 默认虚拟主机)
- [5. 反向代理配置](#5. 反向代理配置)
-
- [5.1 基本反向代理配置](#5.1 基本反向代理配置)
- [5.2 代理特定路径](#5.2 代理特定路径)
- [5.3 代理 WebSocket](#5.3 代理 WebSocket)
- [5.4 代理缓存配置](#5.4 代理缓存配置)
- [6. 负载均衡配置](#6. 负载均衡配置)
-
- [6.1 基本负载均衡配置](#6.1 基本负载均衡配置)
- [6.2 负载均衡算法](#6.2 负载均衡算法)
- [6.3 健康检查与故障转移](#6.3 健康检查与故障转移)
- [7. SSL/TLS 配置与 HTTPS 部署](#7. SSL/TLS 配置与 HTTPS 部署)
-
- [7.1 安装 SSL 证书](#7.1 安装 SSL 证书)
-
- [7.1.1 使用 Let's Encrypt 获取免费证书](#7.1.1 使用 Let's Encrypt 获取免费证书)
- [7.1.2 创建自签名证书(测试用)](#7.1.2 创建自签名证书(测试用))
- [7.2 配置 HTTPS](#7.2 配置 HTTPS)
- [7.3 SSL 配置说明](#7.3 SSL 配置说明)
- [8. 常用模块配置](#8. 常用模块配置)
-
- [8.1 状态监控模块 (stub\_status)](#8.1 状态监控模块 (stub_status))
- [8.2 Gzip 压缩模块](#8.2 Gzip 压缩模块)
- [8.3 防盗链配置](#8.3 防盗链配置)
- [8.4 URL 重写 (rewrite)](#8.4 URL 重写 (rewrite))
- [9. 性能优化实践](#9. 性能优化实践)
-
- [9.1 工作进程优化](#9.1 工作进程优化)
- [9.2 事件处理优化](#9.2 事件处理优化)
- [9.3 连接优化](#9.3 连接优化)
- [9.4 缓存优化](#9.4 缓存优化)
- [9.5 静态资源优化](#9.5 静态资源优化)
- [10. 日志管理与分析](#10. 日志管理与分析)
-
- [10.1 日志配置](#10.1 日志配置)
- [10.2 日志轮转配置](#10.2 日志轮转配置)
- [10.3 日志分析工具](#10.3 日志分析工具)
-
- [10.3.1 awstats](#10.3.1 awstats)
- [10.3.2 goaccess](#10.3.2 goaccess)
- [11. 日常运维与监控](#11. 日常运维与监控)
-
- [11.1 常用运维命令](#11.1 常用运维命令)
- [11.2 监控 Nginx 服务](#11.2 监控 Nginx 服务)
-
- [11.2.1 使用 systemd 监控](#11.2.1 使用 systemd 监控)
- [11.2.2 使用监控脚本](#11.2.2 使用监控脚本)
- [11.2.3 使用专业监控工具](#11.2.3 使用专业监控工具)
- [12. 安全加固措施](#12. 安全加固措施)
-
- [12.1 隐藏 Nginx 版本信息](#12.1 隐藏 Nginx 版本信息)
- [12.2 限制请求方法](#12.2 限制请求方法)
- [12.3 限制请求速率](#12.3 限制请求速率)
- [12.4 限制并发连接数](#12.4 限制并发连接数)
- [12.5 防止 SQL 注入和 XSS 攻击](#12.5 防止 SQL 注入和 XSS 攻击)
- [12.6 更改默认用户](#12.6 更改默认用户)
- [13. 常见问题排查](#13. 常见问题排查)
-
- [13.1 配置文件错误](#13.1 配置文件错误)
- [13.2 端口被占用](#13.2 端口被占用)
- [13.3 403 Forbidden 错误](#13.3 403 Forbidden 错误)
- [13.4 502 Bad Gateway 错误](#13.4 502 Bad Gateway 错误)
- [13.5 504 Gateway Timeout 错误](#13.5 504 Gateway Timeout 错误)
- [14. 实战案例](#14. 实战案例)
-
- [14.1 静态网站部署](#14.1 静态网站部署)
- [14.2 Node.js 应用反向代理](#14.2 Node.js 应用反向代理)
- [14.3 PHP 应用(如 WordPress)配置](#14.3 PHP 应用(如 WordPress)配置)
- [14.4 负载均衡配置(Web 集群)](#14.4 负载均衡配置(Web 集群))
1. Nginx 简介
1.1 什么是 Nginx
Nginx(发音为 "engine x")是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。由俄罗斯程序员 Igor Sysoev 开发,第一个公开版本发布于 2004 年。
1.2 Nginx 的特点
-
高性能:采用异步非阻塞事件驱动模型,能高效处理大量并发连接
-
高可靠性:设计简洁稳定,故障率低
-
高扩展性:模块化结构,支持多种第三方模块
-
低资源消耗:相比 Apache 等服务器,相同硬件配置下能支持更多并发连接
-
功能丰富:支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议,以及反向代理、负载均衡、URL 重写等功能
1.3 Nginx 与 Apache 的对比
| 特性 | Nginx | Apache |
|---|---|---|
| 并发处理模型 | 异步非阻塞 | 多进程 / 多线程 |
| 内存占用 | 低 | 较高 |
| 静态资源处理 | 高效 | 一般 |
| 模块机制 | 静态编译 | 动态加载 |
| 配置风格 | 简洁 | 相对复杂 |
| 重写规则 | 强大 | 强大 |
| 适合场景 | 高并发、静态资源、反向代理 | 动态内容、模块丰富 |
Nginx 的模块机制:静态编译
在 编译阶段 与核心代码一起编译成可执行文件,运行时无法动态添加或移除模块。
-
工作原理
-
编译时集成 :所有需要使用的模块(包括官方模块和第三方模块)必须在编译 Nginx 源码时通过
--with-模块名或--add-module=模块路径显式指定,编译后模块与 Nginx 核心绑定为单一可执行文件。 -
运行时不可变:一旦编译完成,运行过程中无法新增、删除或替换模块,如需修改模块,必须重新编译并替换可执行文件。
-
-
优缺点
-
优点:
-
性能优异:模块与核心紧密集成,减少了动态加载的开销(如磁盘 I/O、内存分配),适合高并发场景。
-
稳定性高:编译时会检查模块兼容性,避免运行时因模块冲突导致的崩溃。
-
资源占用低:无需为动态加载预留额外内存或接口。
-
-
缺点:
-
灵活性差:修改模块必须重新编译,无法在线升级或调整功能。
-
部署成本高:不同业务场景可能需要维护多个不同模块组合的 Nginx 版本。
-
-
Apache 的模块机制:动态加载
Apache 采用 动态共享对象(DSO,Dynamic Shared Object) 机制,模块以独立的动态链接库(.so 文件)形式存在,可在运行时动态加载或卸载,无需重新编译服务器核心。
-
工作原理
- 模块独立编译 :模块单独编译为
.so文件(如mod_rewrite.so、mod_ssl.so),与 Apache 核心分离。 - 配置文件控制加载 :通过配置文件(
httpd.conf或conf.modules.d/目录下的文件)中的LoadModule指令指定需要加载的模块,修改后只需重启或重载 Apache 即可生效。
- 模块独立编译 :模块单独编译为
-
优缺点
- 优点:
- 灵活性高:无需重新编译即可添加 / 移除模块,便于按需扩展功能。
- 维护成本低:一个 Apache 实例可通过配置加载不同模块,适应多种场景。
- 升级方便:模块可单独升级,无需替换整个服务器核心。
- 缺点:
- 性能开销:动态加载会增加一定的内存占用和运行时开销(如符号解析、内存映射)。
- 兼容性风险:不同版本模块可能存在冲突,需严格匹配 Apache 核心版本。
- 优点:
1.4 Nginx 主要应用场景
-
静态资源服务器(HTML、CSS、JavaScript、图片等)
-
反向代理服务器
-
负载均衡器
-
HTTP 缓存服务器
-
API 网关
-
动静分离部署
-
SSL 终端代理
2. 安装与初始化配置
2.1 安装方式选择
CentOS 7 上安装 Nginx 主要有两种方式:官方源安装和源码编译安装。
2.1.1 官方源安装(推荐)
官方源提供了最新稳定版的 Nginx,安装和更新都非常方便:
bash
# 安装官方源
cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
# 安装 nginx
yum install -y nginx
# 启动并设置开机自启
systemctl start nginx
systemctl enable nginx
# 验证安装
nginx -v # 显示版本信息
systemctl status nginx # 检查服务状态
2.1.2 源码编译安装
当需要特定模块或自定义编译选项时,可选择源码编译安装:
bash
# 安装依赖包
yum install -y gcc gcc-c++ make zlib-devel pcre-devel openssl-devel wget
# 创建系统用户
useradd -M -s /sbin/nologin nginx
# 下载源码包(请从官网获取最新稳定版地址)
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# 配置编译选项
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-pcre \
--with-stream \
--with-http_gzip_static_module
# 编译安装
make && make install
# 创建 systemd 服务文件
cat > /usr/lib/systemd/system/nginx.service << 'EOF'
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
# 启动服务
systemctl daemon-reload
systemctl start nginx
systemctl enable nginx
2.2 目录结构
官方源安装的 Nginx 主要目录结构:
bash
/etc/nginx/ # 配置文件主目录
├── nginx.conf # 主配置文件
├── conf.d/ # 子配置文件目录
├── default.d/ # 默认服务器配置
├── koi-utf
├── koi-win
├── mime.types # MIME类型定义
├── scgi_params # SCGI参数
├── uwsgi_params # uWSGI参数
└── win-utf
/usr/share/nginx/html/ # 默认网站根目录
/var/log/nginx/ # 日志目录
/var/cache/nginx/ # 缓存目录
/usr/sbin/nginx # 可执行程序
2.3 防火墙配置
bash
# 开放 HTTP (80) 和 HTTPS (443) 端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --reload
# 查看开放的端口
firewall-cmd --zone=public --list-ports
2.4 基本操作命令
bash
# 检查配置文件语法
nginx -t
# 启动 Nginx
systemctl start nginx
# 停止 Nginx
systemctl stop nginx
# 重启 Nginx
systemctl restart nginx
# 平滑重启(不中断服务)
systemctl reload nginx
# 或
nginx -s reload
# 查看 Nginx 状态
systemctl status nginx
# 设置开机自启
systemctl enable nginx
# 禁止开机自启
systemctl disable nginx
3. 核心配置文件详解
Nginx 的主配置文件是 /etc/nginx/nginx.conf(官方源安装)或 /usr/local/nginx/conf/nginx.conf(源码安装)。
3.1 配置文件结构
Nginx 配置文件采用块级结构,主要包含以下几个层级:
bash
main # 全局配置
├── events # 事件处理配置
├── http # HTTP 协议配置
│ ├── upstream # 上游服务器配置(用于反向代理和负载均衡)
│ ├── server # 虚拟主机配置
│ │ ├── location # URL 匹配配置
│ │ └── ...
│ └── ...
├── stream # TCP/UDP 代理配置(可选)
└── ...
3.2 全局配置 (main)
全局配置部分设置 Nginx 服务器的基本运行参数:
nginx
# 用户和组
user nginx;
# 工作进程数,建议设置为 CPU 核心数
worker_processes auto;
# 错误日志路径和级别(debug, info, notice, warn, error, crit)
error_log /var/log/nginx/error.log warn;
# PID 文件路径
pid /var/run/nginx.pid;
3.3 事件配置 (events)
事件配置部分设置 Nginx 处理连接的方式:
nginx
events {
# 每个工作进程的最大连接数
worker_connections 1024;
# 事件模型,Linux 推荐使用 epoll
use epoll;
# 是否允许同时接收多个网络连接
multi_accept on;
}
3.4 HTTP 配置 (http)
HTTP 配置部分是 Nginx 最核心的配置,包含了所有与 HTTP 协议相关的设置:
nginx
http {
# 引入 MIME 类型定义文件
include /etc/nginx/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" "$http_x_forwarded_for"';
# 访问日志路径
access_log /var/log/nginx/access.log main;
# 启用 sendfile 系统调用,加速文件传输
sendfile on;
# 启用 tcp_nopush,在 sendfile 开启时有效
tcp_nopush on;
# 启用 tcp_nodelay,在 keepalive 连接时有效
tcp_nodelay on;
# 长连接超时时间
keepalive_timeout 65;
# 启用 gzip 压缩
gzip on;
# 引入其他配置文件
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
3.5 配置文件常用指令说明
| 指令 | 作用 | 示例 |
|---|---|---|
worker_processes |
设置工作进程数量 | worker_processes 4; 或 worker_processes auto; |
worker_connections |
每个工作进程的最大连接数 | worker_connections 1024; |
use |
指定事件处理模型 | use epoll; |
log_format |
定义日志格式 | 见上文示例 |
access_log |
设置访问日志 | access_log /var/log/nginx/access.log main; |
error_log |
设置错误日志 | error_log /var/log/nginx/error.log warn; |
sendfile |
启用 sendfile 系统调用 | sendfile on; |
keepalive_timeout |
设置长连接超时时间 | keepalive_timeout 65; |
gzip |
启用 gzip 压缩 | gzip on; |
include |
引入其他配置文件 | include /etc/nginx/conf.d/*.conf; |
4. 虚拟主机配置实践
虚拟主机(Virtual Host)允许在同一台服务器上托管多个网站,Nginx 支持基于域名、IP 和端口的虚拟主机。
4.1 基于域名的虚拟主机
这是最常用的虚拟主机配置方式,通过不同的域名区分不同的网站。
4.1.1 创建目录结构
bash
# 创建网站根目录
mkdir -p /var/www/{example.com,test.com}/{html,logs}
# 设置权限
chown -R nginx:nginx /var/www/
chmod -R 755 /var/www/
# 创建测试页面
echo "Welcome to example.com" > /var/www/example.com/html/index.html
echo "Welcome to test.com" > /var/www/test.com/html/index.html
4.1.2 配置虚拟主机
创建 example.com 的配置文件:
bash
cat > /etc/nginx/sites-available/example.com.conf << 'EOF'
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
access_log /var/www/example.com/logs/access.log main;
error_log /var/www/example.com/logs/error.log warn;
location / {
try_files $uri $uri/ =404;
}
}
EOF
创建 test.com 的配置文件:
cat > /etc/nginx/sites-available/test.com.conf << 'EOF'
server {
listen 80;
server_name test.com www.test.com;
root /var/www/test.com/html;
index index.html index.htm;
access_log /var/www/test.com/logs/access.log main;
error_log /var/www/test.com/logs/error.log warn;
location / {
try_files $uri $uri/ =404;
}
}
EOF
启用虚拟主机配置:
bash
# 创建软链接到 sites-enabled 目录
ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/test.com.conf /etc/nginx/sites-enabled/
# 检查配置并重启
nginx -t
systemctl reload nginx
4.1.3 测试配置
在本地 hosts 文件中添加域名解析(或在 DNS 服务器中配置):
ini
192.168.1.100 example.com www.example.com
192.168.1.100 test.com www.test.com
然后通过浏览器访问这两个域名,应该能看到不同的页面内容。
4.2 基于端口的虚拟主机
通过不同的端口区分不同的网站:
bash
cat > /etc/nginx/sites-available/example-8080.conf << 'EOF'
server {
listen 8080;
server_name example.com;
root /var/www/example-8080/html;
index index.html index.htm;
access_log /var/www/example-8080/logs/access.log main;
error_log /var/www/example-8080/logs/error.log warn;
location / {
try_files $uri $uri/ =404;
}
}
EOF
开放 8080 端口:
bash
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload
启用配置:
bash
ln -s /etc/nginx/sites-available/example-8080.conf /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
4.3 基于 IP 的虚拟主机
如果服务器有多个 IP 地址,可以基于 IP 地址配置虚拟主机:
nginx
server {
listen 192.168.1.100:80;
# 无需设置 server_name 或设置为 _
server_name _;
root /var/www/ip1/html;
# 其他配置...
}
server {
listen 192.168.1.101:80;
server_name _;
root /var/www/ip2/html;
# 其他配置...
}
4.4 默认虚拟主机
默认虚拟主机是指当请求的域名没有匹配到任何虚拟主机时,Nginx 会使用的虚拟主机配置:
nginx
cat > /etc/nginx/sites-available/default.conf << 'EOF'
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/default/html;
index index.html;
# 返回 403 禁止访问未知域名
# location / {
# return 403;
# }
# 或者重定向到一个默认域名
# return 301 http://example.com$request_uri;
}
EOF
5. 反向代理配置
反向代理是 Nginx 最常用的功能之一,它可以将客户端请求转发到后端服务器,并将后端服务器的响应返回给客户端。
5.1 基本反向代理配置
nginx
server {
listen 80;
server_name proxy.example.com;
# 反向代理配置
location / {
proxy_pass http://127.0.0.1:8080; # 后端服务器地址
proxy_set_header Host $host; # 传递主机名
proxy_set_header X-Real-IP $remote_addr; # 传递真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
5.2 代理特定路径
只代理特定路径,其他路径由 Nginx 直接处理:
nginx
server {
listen 80;
server_name example.com;
root /var/www/example.com/html;
index index.html;
# 只代理 /api 路径
location /api {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 其他路径由 Nginx 直接处理
location / {
try_files $uri $uri/ =404;
}
}
5.3 代理 WebSocket
WebSocket 协议需要特殊配置以支持长连接:
nginx
location /ws {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
5.4 代理缓存配置
启用代理缓存可以减轻后端服务器压力,提高响应速度:
nginx
# 在 http 块中定义缓存
http {
# ... 其他配置 ...
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=proxy_cache:10m max_size=10g
inactive=60m use_temp_path=off;
server {
# ... 服务器配置 ...
location / {
proxy_pass http://backend_server;
# 启用缓存
proxy_cache proxy_cache;
proxy_cache_valid 200 304 10m; # 200和304响应缓存10分钟
proxy_cache_valid any 1m; # 其他响应缓存1分钟
proxy_cache_key "$scheme$request_method$host$request_uri";
# 缓存控制
add_header X-Proxy-Cache $upstream_cache_status;
}
}
}
6. 负载均衡配置
Nginx 可以作为负载均衡器,将请求分发到多个后端服务器,提高系统的可用性和处理能力。
6.1 基本负载均衡配置
nginx
http {
# 定义上游服务器组
upstream backend_servers {
server 192.168.1.101:80;
server 192.168.1.102:80;
server 192.168.1.103:80;
}
server {
listen 80;
server_name lb.example.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
6.2 负载均衡算法
Nginx 支持多种负载均衡算法,默认是轮询(round robin):
-
轮询(Round Robin):默认算法,请求按顺序分发到每个服务器
nginxupstream backend_servers { server 192.168.1.101:80; server 192.168.1.102:80; server 192.168.1.103:80; } -
权重(Weight):根据权重分配请求,权重越高,分配的请求越多
nginxupstream backend_servers { server 192.168.1.101:80 weight=3; # 30% 的请求 server 192.168.1.102:80 weight=3; # 30% 的请求 server 192.168.1.103:80 weight=4; # 40% 的请求 } -
IP 哈希(IP Hash):根据客户端 IP 地址的哈希结果分配请求,确保同一客户端始终访问同一服务器
nginxupstream backend_servers { ip_hash; server 192.168.1.101:80; server 192.168.1.102:80; server 192.168.1.103:80; } -
最少连接(Least Connections):将请求分配到当前连接数最少的服务器
nginxupstream backend_servers { least_conn; server 192.168.1.101:80; server 192.168.1.102:80; server 192.168.1.103:80; }
6.3 健康检查与故障转移
配置服务器健康检查和自动故障转移:
nginx
upstream backend_servers {
server 192.168.1.101:80 max_fails=3 fail_timeout=30s;
server 192.168.1.102:80 max_fails=3 fail_timeout=30s;
server 192.168.1.103:80 backup; # 备用服务器,只有主服务器都不可用时才启用
}
-
max_fails:允许请求失败的次数,默认 1 -
fail_timeout:失败后暂停多长时间不再请求该服务器,默认 10 秒 -
backup:标记为备用服务器
7. SSL/TLS 配置与 HTTPS 部署
7.1 安装 SSL 证书
可以通过 Let's Encrypt 获取免费证书,或使用自签名证书进行测试。
7.1.1 使用 Let's Encrypt 获取免费证书
bash
# 安装 Certbot
yum install -y epel-release
yum install -y certbot python2-certbot-nginx
# 获取并自动配置证书
certbot --nginx -d example.com -d www.example.com
7.1.2 创建自签名证书(测试用)
bash
# 创建证书目录
mkdir -p /etc/nginx/ssl
# 生成自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/example.com.key \
-out /etc/nginx/ssl/example.com.crt
7.2 配置 HTTPS
nginx
server {
listen 80;
server_name example.com www.example.com;
# 将 HTTP 请求重定向到 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 证书配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/example.com.crt;
# 网站根目录和索引文件
root /var/www/example.com/html;
index index.html;
# 其他配置...
location / {
try_files $uri $uri/ =404;
}
}
7.3 SSL 配置说明
| 配置项 | 作用 |
|---|---|
ssl_protocols |
指定支持的 TLS 协议版本 |
ssl_ciphers |
指定加密套件,优先选择安全性高的套件 |
ssl_prefer_server_ciphers |
优先使用服务器端的加密套件 |
ssl_session_cache |
启用 SSL 会话缓存,提高性能 |
ssl_session_timeout |
SSL 会话超时时间 |
ssl_stapling |
启用 OCSP stapling,提高 TLS 握手性能 |
ssl_stapling_verify |
验证 OCSP 响应 |
8. 常用模块配置
8.1 状态监控模块 (stub_status)
nginx
server {
# ... 其他配置 ...
location /nginx_status {
stub_status on;
access_log off;
# 限制访问来源
allow 192.168.1.0/24;
allow 127.0.0.1;
deny all;
}
}
访问 /nginx_status 可以看到类似以下的输出:
nginx
Active connections: 2
server accepts handled requests
100 100 300
Reading: 0 Writing: 1 Waiting: 1
-
Active connections:当前活跃的连接数 -
accepts:总接受的连接数 -
handled:总处理的连接数 -
requests:总请求数 -
Reading:正在读取客户端请求的连接数 -
Writing:正在向客户端发送响应的连接数 -
Waiting:处于空闲状态的连接数
8.2 Gzip 压缩模块
nginx
http {
# ... 其他配置 ...
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6; # 压缩级别,1-9,级别越高压缩率越高但消耗CPU越多
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
8.3 防盗链配置
nginx
server {
# ... 其他配置 ...
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
# 允许自己的域名和百度、谷歌等搜索引擎访问
valid_referers none blocked example.com *.example.com *.baidu.com *.google.com;
# 如果不是允许的来源,则返回403或指定图片
if ($invalid_referer) {
return 403;
# 或者返回一张防盗链图片
# rewrite ^/ https://example.com/anti-leech.jpg last;
}
}
}
8.4 URL 重写 (rewrite)
nginx
server {
# ... 其他配置 ...
# 将不带 www 的域名重定向到带 www 的域名
if ($host = 'example.com') {
return 301 https://www.example.com$request_uri;
}
# 将 .html 后缀的 URL 重写为无后缀
rewrite ^/(.*)\.html$ /$1 permanent;
# 伪静态配置示例(适合 PHP 框架)
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
9. 性能优化实践
9.1 工作进程优化
nginx
# 设置为 CPU 核心数
worker_processes auto;
# 绑定工作进程到特定 CPU 核心(提高缓存利用率)
worker_cpu_affinity 0001 0010 0100 1000; # 4 核心 CPU 示例
# 每个工作进程的最大打开文件数
worker_rlimit_nofile 65535;
9.2 事件处理优化
nginx
events {
worker_connections 10240; # 提高每个工作进程的最大连接数
use epoll; # 使用 epoll 事件模型
multi_accept on; # 允许同时接受多个连接
}
9.3 连接优化
nginx
http {
# ... 其他配置 ...
# 启用长连接
keepalive_timeout 65;
keepalive_requests 100; # 长连接上允许的最大请求数
# TCP 优化
tcp_nopush on; # 发送数据时先缓存,直到缓存满或超时
tcp_nodelay on; # 禁用 Nagle 算法,减少延迟
# 客户端请求头读取超时
client_header_timeout 15;
# 客户端请求体读取超时
client_body_timeout 15;
# 发送响应超时
send_timeout 15;
}
9.4 缓存优化
nginx
http {
# ... 其他配置 ...
# 开启文件缓存
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# 启用 gzip 压缩
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
9.5 静态资源优化
nginx
server {
# ... 其他配置 ...
# 静态资源缓存设置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d; # 设置 30 天缓存
add_header Cache-Control "public, max-age=2592000";
access_log off; # 不记录静态资源访问日志
}
# 大型静态文件优化
location ~* \.(zip|rar|7z|tar|gz|bz2)$ {
expires 7d;
add_header Cache-Control "public, max-age=604800";
tcp_nopush on;
sendfile on;
}
}
10. 日志管理与分析
10.1 日志配置
nginx
http {
# 定义主日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time';
# 定义访问日志
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# 虚拟主机日志配置
server {
server_name example.com;
access_log /var/log/nginx/example.com.access.log main;
error_log /var/log/nginx/example.com.error.log error;
# ... 其他配置 ...
}
}
10.2 日志轮转配置
创建日志轮转配置文件:
bash
cat > /etc/logrotate.d/nginx << 'EOF'
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
EOF
配置说明:
-
daily:每天轮转一次 -
missingok:忽略缺失的日志文件 -
rotate 14:保留 14 天的日志 -
compress:压缩轮转后的日志 -
delaycompress:延迟压缩,不压缩最近一次轮转的日志 -
notifempty:如果日志为空则不轮转 -
create 0640 nginx adm:创建新日志文件的权限和所有者 -
postrotate:轮转后执行的命令,通知 Nginx 重新打开日志文件
10.3 日志分析工具
10.3.1 awstats
bash
# 安装 awstats
yum install -y awstats
# 配置 awstats
cp /etc/awstats/awstats.model.conf /etc/awstats/awstats.example.com.conf
# 编辑配置文件,修改以下内容
# SiteDomain="example.com"
# LogFile="/var/log/nginx/example.com.access.log"
# LogFormat=1
# 生成统计报告
awstats_updateall.pl now
# 设置定时任务
echo "0 0 * * * /usr/share/awstats/wwwroot/cgi-bin/awstats_updateall.pl now" >> /etc/crontab
10.3.2 goaccess
bash
# 安装 goaccess
yum install -y goaccess
# 实时分析日志
goaccess /var/log/nginx/access.log -c
# 生成 HTML 报告
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED
11. 日常运维与监控
11.1 常用运维命令
bash
# 检查配置文件
nginx -t
# 平滑重启
nginx -s reload
# 查看 Nginx 版本和编译参数
nginx -V
# 查看 Nginx 进程
ps aux | grep nginx
# 查看 Nginx 占用的端口
netstat -tlnp | grep nginx
# 或
ss -tlnp | grep nginx
# 查看连接数统计
netstat -an | grep :80 | wc -l
11.2 监控 Nginx 服务
11.2.1 使用 systemd 监控
bash
systemctl status nginx
11.2.2 使用监控脚本
创建一个简单的监控脚本:
bash
cat > /usr/local/bin/nginx_monitor.sh << 'EOF'
#!/bin/bash
NGINX_PID=$(cat /var/run/nginx.pid)
if [ -z "$NGINX_PID" ]; then
echo "Nginx is not running, starting it..."
systemctl start nginx
exit 1
fi
if ! ps -p $NGINX_PID > /dev/null; then
echo "Nginx process $NGINX_PID not found, restarting..."
systemctl restart nginx
exit 1
fi
echo "Nginx is running normally (PID: $NGINX_PID)"
exit 0
EOF
# 赋予执行权限
chmod +x /usr/local/bin/nginx_monitor.sh
添加到定时任务:
bash
echo "*/5 * * * * /usr/local/bin/nginx_monitor.sh >> /var/log/nginx/monitor.log 2>&1" >> /etc/crontab
11.2.3 使用专业监控工具
-
Zabbix:可以通过 Zabbix Agent 监控 Nginx 状态
-
Prometheus + Grafana:配合 nginx-exporter 监控 Nginx 性能指标
安装 nginx-exporter:
bash# 下载并安装 wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v0.11.0/nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz tar zxvf nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz cp nginx-prometheus-exporter /usr/local/bin/ # 创建 systemd 服务 cat > /etc/systemd/system/nginx-exporter.service << 'EOF' [Unit] Description=Nginx Prometheus Exporter After=network.target [Service] User=nginx Group=nginx ExecStart=/usr/local/bin/nginx-prometheus-exporter -nginx.scrape-uri=http://localhost/nginx_status [Install] WantedBy=multi-user.target EOF # 启动服务 systemctl start nginx-exporter systemctl enable nginx-exporter
12. 安全加固措施
12.1 隐藏 Nginx 版本信息
nginx
http {
# 隐藏版本信息
server_tokens off;
# ... 其他配置 ...
}
12.2 限制请求方法
nginx
server {
# ... 其他配置 ...
# 只允许 GET, HEAD, POST 请求方法
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}
}
12.3 限制请求速率
nginx
http {
# 定义限流规则
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
server {
# ... 其他配置 ...
# 应用限流规则
location / {
limit_req zone=req_limit burst=20 nodelay;
# ... 其他配置 ...
}
}
}
-
rate=10r/s:限制每秒 10 个请求 -
burst=20:允许 20 个请求的突发流量 -
nodelay:不延迟处理突发请求
12.4 限制并发连接数
nginx
http {
# 定义连接限制规则
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
# ... 其他配置 ...
# 应用连接限制
location / {
limit_conn conn_limit 10; # 每个 IP 最多 10 个并发连接
# ... 其他配置 ...
}
}
}
12.5 防止 SQL 注入和 XSS 攻击
nginx
server {
# ... 其他配置 ...
# 过滤常见的 SQL 注入字符
if ($request_uri ~* "union.*select.*\(") {
return 403;
}
if ($request_uri ~* "union.*all.*select.*") {
return 403;
}
if ($request_uri ~* "concat.*\(") {
return 403;
}
# 添加安全响应头
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Content-Security-Policy "default-src 'self'" always;
}
12.6 更改默认用户
bash
# 创建新用户
useradd -M -s /sbin/nologin nginx_user
# 修改 Nginx 配置
sed -i 's/^user nginx;/user nginx_user;/' /etc/nginx/nginx.conf
# 更改文件权限
chown -R nginx_user:nginx_user /var/www/
chown -R nginx_user:nginx_user /var/log/nginx/
chown -R nginx_user:nginx_user /var/cache/nginx/
# 重启 Nginx
systemctl restart nginx
13. 常见问题排查
13.1 配置文件错误
bash
# 检查配置文件语法
nginx -t
# 查看错误日志
tail -f /var/log/nginx/error.log
常见配置错误:
-
缺少分号
; -
括号不匹配
-
指令拼写错误
-
端口被占用
13.2 端口被占用
bash
# 查看端口占用情况
netstat -tlnp | grep 80
# 或
ss -tlnp | grep 80
# 终止占用端口的进程
kill -9 <进程ID>
13.3 403 Forbidden 错误
可能原因及解决方法:
-
文件权限问题:确保 Nginx 用户有访问文件的权限
bashchown -R nginx:nginx /var/www/ chmod -R 755 /var/www/ -
SELinux 限制:临时关闭 SELinux 测试
bashsetenforce 0如果问题解决,可永久设置 SELinux 规则:
bashchcon -R -t httpd_sys_content_t /var/www/ -
目录索引问题:确保目录有索引文件或配置了 autoindex
bashlocation / { index index.html index.htm; # 或启用目录浏览 # autoindex on; }
13.4 502 Bad Gateway 错误
通常是后端服务器问题:
-
检查后端服务器是否运行,例如php-fpm.service
bashsystemctl status php-fpm.service -
检查后端服务器是否监听正确的端口
bashnetstat -tlnp | grep <后端端口> -
检查防火墙是否允许 Nginx 访问后端服务器
bashfirewall-cmd --zone=public --add-port=<后端端口>/tcp --permanent firewall-cmd --reload -
查看 Nginx 错误日志获取更多信息
bashtail -f /var/log/nginx/error.log
13.5 504 Gateway Timeout 错误
后端服务器响应超时:
nginx
location / {
proxy_pass http://backend_server;
proxy_connect_timeout 60s; # 连接超时时间
proxy_send_timeout 60s; # 发送超时时间
proxy_read_timeout 60s; # 读取超时时间
}
14. 实战案例
14.1 静态网站部署
nginx
server {
listen 80;
listen 443 ssl http2;
server_name static.example.com;
# SSL 配置
ssl_certificate /etc/nginx/ssl/static.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/static.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# 网站根目录
root /var/www/static.example.com;
index index.html index.htm;
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
access_log off;
}
# 启用 gzip 压缩
gzip on;
gzip_types text/plain text/css application/javascript text/xml application/xml application/xml+rss text/javascript;
# 日志配置
access_log /var/log/nginx/static.example.com.access.log main;
error_log /var/log/nginx/static.example.com.error.log warn;
}
14.2 Node.js 应用反向代理
nginx
server {
listen 80;
server_name node.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name node.example.com;
ssl_certificate /etc/nginx/ssl/node.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/node.example.com.key;
# 其他 SSL 配置...
# 反向代理到 Node.js 应用
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 120s;
}
# 静态资源由 Nginx 直接处理
location /static {
alias /var/www/node.example.com/static;
expires 1d;
add_header Cache-Control "public, max-age=86400";
}
}
14.3 PHP 应用(如 WordPress)配置
nginx
server {
listen 80;
server_name wordpress.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name wordpress.example.com;
ssl_certificate /etc/nginx/ssl/wordpress.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/wordpress.example.com.key;
# 其他 SSL 配置...
root /var/www/wordpress.example.com;
index index.php index.html;
# PHP 处理
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000; # PHP-FPM 监听地址
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 超时设置
fastcgi_connect_timeout 30s;
fastcgi_send_timeout 30s;
fastcgi_read_timeout 60s;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
expires 7d;
add_header Cache-Control "public, max-age=604800";
access_log off;
}
# WordPress 固定链接支持
location / {
try_files $uri $uri/ /index.php?$args;
}
}
14.4 负载均衡配置(Web 集群)
nginx
http {
# 上游服务器配置
upstream web_servers {
ip_hash; # 确保会话一致性
server 192.168.1.101:80 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.102:80 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.103:80 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.104:80 backup; # 备用服务器
}
# 负载均衡器配置
server {
listen 80;
listen 443 ssl http2;
server_name cluster.example.com;
ssl_certificate /etc/nginx/ssl/cluster.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/cluster.example.com.key;
# 其他 SSL 配置...
# 代理到上游服务器
location / {
proxy_pass http://web_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 代理缓存配置
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=web_cache:100m max_size=10g inactive=60m;
proxy_cache web_cache;
proxy_cache_valid 200 304 10m;
proxy_cache_valid any 1m;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
proxy_pass http://web_servers;
proxy_set_header Host $host;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
proxy_cache web_cache;
proxy_cache_valid 200 304 30d;
}
}
}