2026-04-09 01:28:15 +08:00

1882 lines
54 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nginx 实战指南
## 目录
1. [Web 服务基础](#1-web-服务基础)
2. [HTTP 协议](#2-http-协议)
3. [I/O 模型](#3-io-模型)
4. [Nginx 介绍和架构](#4-nginx-介绍和架构)
5. [Nginx 安装](#5-nginx-安装)
6. [Nginx 各种模块实现 Web 服务](#6-nginx-各种模块实现-web-服务)
7. [Nginx 实现 HTTP 负载均衡](#7-nginx-实现-http-负载均衡)
8. [Nginx 实现 TCP 反向代理](#8-nginx-实现-tcp-反向代理)
9. [Nginx 实现 FastCGI 反向代理](#9-nginx-实现-fastcgi-反向代理)
10. [Nginx 二次开发版](#10-nginx-二次开发版)
11. [Nginx 高并发 Linux 内核优化](#11-nginx-高并发-linux-内核优化)
---
## 1. Web 服务基础
### 1.1 Web 服务概念
Web 服务是一种基于 HTTP/HTTPS 协议的网络服务架构,主要分为前端(浏览器)和后端(服务器)两部分。
### 1.2 Web 服务架构演进
```
┌─────────────────────────────────────────────────────┐
│ Web 服务架构演进 │
├─────────────────────────────────────────────────────┤
│ │
│ 单机架构 集群架构 │
│ ┌──────────┐ ┌────────┬────────┐ │
│ │ Apache │ │ Load │nginx │ │
│ │ + PHP │ │ Balancer│ │ │
│ └──────────┘ └─┬──────┴────────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │App 1 │ │App 2 │ │App 3 │ │
│ └───────┘ └───────┘ └───────┘ │
│ │
│ 微服务架构 云原生架构 │
│ ┌────┬────┬────┐ ┌─────┬─────┬─────┐ │
│ │API│Auth│Order│ │K8s │Docker│Istio│ │
│ │Gateway│ │ │ │ │ │ │ │
│ └────┴────┴────┘ └─────┴─────┴─────┘ │
│ │
└─────────────────────────────────────────────────────┘
```
### 1.3 常见 Web 服务器
| 服务器 | 特点 | 适用场景 |
|--------|------|----------|
| Apache | 功能丰富,模块化,稳定 | 传统 Web 应用 |
| Nginx | 高性能,低内存,反向代理 | 高并发,负载均衡 |
| IIS | Windows 原生,集成 AD | Windows 环境 |
| Tomcat | Java 容器Servlet 容器 | Java 应用 |
| Jetty | 轻量级,嵌入式 | 微服务 |
---
## 2. HTTP 协议
### 2.1 HTTP 协议概述
HTTPHyperText Transfer Protocol是互联网应用最广泛的网络协议属于应用层协议。
### 2.2 HTTP 请求结构
```
┌─────────────────────────────────────────────────────┐
│ HTTP 请求结构 │
├─────────────────────────────────────────────────────┤
│ │
│ 请求行GET /index.html HTTP/1.1 │
│ ┌─────────────────────────────────────────────┐ │
│ │ 方法 URL 协议版本 │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ 请求头: │
│ Host: www.example.com │
│ User-Agent: Mozilla/5.0 │
│ Accept: text/html,application/json │
│ Accept-Language: zh-CN,zh;q=0.9 │
│ Cookie: session=xxx │
│ │
│ 空行 │
│ │
│ 请求体POST/PUT
│ username=admin&password=123456 │
│ │
└─────────────────────────────────────────────────────┘
```
### 2.3 HTTP 响应结构
```
┌─────────────────────────────────────────────────────┐
│ HTTP 响应结构 │
├─────────────────────────────────────────────────────┤
│ │
│ 状态行HTTP/1.1 200 OK │
│ ┌─────────────────────────────────────────────┐ │
│ │ 协议版本 状态码 状态描述 │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ 响应头: │
│ Server: nginx/1.24.0 │
│ Content-Type: text/html; charset=utf-8 │
│ Content-Length: 1234 │
│ Date: Thu, 09 Apr 2026 01:17:00 GMT │
│ Set-Cookie: session=xxx; HttpOnly │
│ │
│ 空行 │
│ │
│ 响应体: │
│ <html>... │
│ │
└─────────────────────────────────────────────────────┘
```
### 2.4 HTTP 方法
| 方法 | 说明 | 幂等 |
|------|------|------|
| GET | 获取资源 | 是 |
| POST | 创建资源 | 否 |
| PUT | 更新资源(完整) | 是 |
| PATCH | 更新资源(部分) | 否 |
| DELETE | 删除资源 | 是 |
| HEAD | 获取响应头 | 是 |
| OPTIONS | 获取支持的请求方法 | 是 |
| CONNECT | 建立隧道 | - |
### 2.5 HTTP 状态码
| 状态码 | 说明 |
|--------|------|
| **1xx** | 信息响应 |
| 100 | Continue |
| 101 | Switching Protocols |
| **2xx** | 成功响应 |
| 200 | OK |
| 201 | Created |
| 204 | No Content |
| 206 | Partial Content |
| **3xx** | 重定向 |
| 301 | Moved Permanently |
| 302 | Found |
| 304 | Not Modified |
| 307 | Temporary Redirect |
| **4xx** | 客户端错误 |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 405 | Method Not Allowed |
| 409 | Conflict |
| 429 | Too Many Requests |
| **5xx** | 服务器错误 |
| 500 | Internal Server Error |
| 502 | Bad Gateway |
| 503 | Service Unavailable |
| 504 | Gateway Timeout |
### 2.6 HTTP 头部
#### 2.6.1 通用头部
| 头部 | 说明 |
|------|------|
| Connection | 连接管理 |
| Transfer-Encoding | 传输编码 |
| Cache-Control | 缓存控制 |
| Date | 日期时间 |
#### 2.6.2 请求头部
| 头部 | 说明 |
|------|------|
| Host | 目标主机 |
| User-Agent | 客户端标识 |
| Accept | 可接受的媒体类型 |
| Accept-Encoding | 可接受的编码 |
| Accept-Language | 可接受的语言 |
| Cookie | Cookie 数据 |
| Referer | 来源页面 |
| Origin | 跨域请求源 |
#### 2.6.3 响应头部
| 头部 | 说明 |
|------|------|
| Server | 服务器信息 |
| Content-Type | 内容类型 |
| Content-Length | 内容长度 |
| Set-Cookie | 设置 Cookie |
| Location | 重定向地址 |
| ETag | 资源版本标识 |
| Last-Modified | 最后修改时间 |
| Expires | 过期时间 |
### 2.7 HTTPS 原理
```
┌─────────────────────────────────────────────────────┐
│ HTTPS 握手流程 │
├─────────────────────────────────────────────────────┤
│ │
│ 1. Client Hello │
│ ← 客户端发送支持的加密套件 │
│ │
│ 2. Server Hello + Certificate + Key Exchange │
│ ← 服务器发送证书和公钥 │
│ │
│ 3. Certificate Verify + Finished │
│ ← 客户端验证证书,生成预主密钥 │
│ │
│ 4. Finished │
│ ← 服务器生成会话密钥 │
│ │
│ 5. 加密通信开始 │
│ │
│ 密码套件示例TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384│
│ - ECDHE: 密钥交换算法 │
│ - RSA: 签名算法 │
│ - AES_256_GCM: 对称加密算法 │
│ - SHA384: 消息认证码 │
│ │
└─────────────────────────────────────────────────────┘
```
---
## 3. I/O 模型
### 3.1 I/O 模型概述
I/O 模型决定了服务器如何处理并发请求,主要有五种模型:
### 3.2 阻塞 I/OBIO
```
┌─────────────────────────────────────────────────────┐
│ 阻塞 I/O 模型 │
├─────────────────────────────────────────────────────┤
│ │
│ 进程/线程 │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ recv() │ ──→ 等待数据 │
│ │ 阻塞 │ ←── 数据到达 │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ 处理数据 │
│ │
│ 特点:每个连接一个线程,资源消耗大 │
│ │
└─────────────────────────────────────────────────────┘
```
### 3.3 非阻塞 I/ONIO
```
┌─────────────────────────────────────────────────────┐
│ 非阻塞 I/O 模型 │
├─────────────────────────────────────────────────────┤
│ │
│ 进程/线程 │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ recv() │ ──→ 立即返回(无数据) │
│ │ 非阻塞 │ ←── 返回 EAGAIN │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ 处理其他事务 │
│ │ │
│ ▼ │
│ 再次调用 recv() │
│ │
│ 特点需要轮询CPU 空转 │
│ │
└─────────────────────────────────────────────────────┘
```
### 3.4 I/O 多路复用Select/Epoll
```
┌─────────────────────────────────────────────────────┐
│ I/O 多路复用模型 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Select/Epoll │ │
│ │ 监控多个 fd 集合 │ │
│ └──────────────┬───────────────────────────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌────┐ ┌────┐ ┌────┐ │
│ │ fd1│ │ fd2│ │ fd3│ │
│ └────┘ └────┘ └────┘ │
│ │
│ 特点:一个线程管理多个连接 │
│ │
└─────────────────────────────────────────────────────┘
```
#### 3.4.1 Select 模型
```c
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd1, &readfds);
FD_SET(fd2, &readfds);
// 阻塞等待
select(maxfd + 1, &readfds, NULL, NULL, NULL);
// 遍历检查
for (i = 0; i < maxfd; i++) {
if (FD_ISSET(i, &readfds)) {
// 处理可读事件
}
}
```
#### 3.4.2 Epoll 模型
```c
// 创建 epoll 实例
int epfd = epoll_create1(0);
// 添加监听
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = fd1;
epoll_ctl(epfd, EPOLL_CTL_ADD, fd1, &ev);
// 等待事件
struct epoll_event events[1024];
int n = epoll_wait(epfd, events, 1024, -1);
// 处理事件
for (int i = 0; i < n; i++) {
// 处理 events[i].data.fd
}
```
### 3.5 信号驱动 I/OSIGIO
```c
// 设置信号处理函数
signal(SIGIO, sigio_handler);
// 设置异步 I/O
fcntl(fd, F_SETOWN, getpid());
fcntl(fd, F_SETFL, O_ASYNC);
// 信号处理
void sigio_handler(int sig) {
// 处理 I/O 事件
}
```
### 3.6 异步 I/OAI/O
```c
struct aiocb cb;
bzero(&cb, sizeof(cb));
cb.aio_fildes = fd;
cb.aio_buf = buffer;
cb.aio_nbytes = 1024;
cb.aio_sigevent.sigev_notify = SIGEV_THREAD;
// 发起异步读
aio_read(&cb);
// 其他操作...
// 等待完成
aio_suspend(&cb, 1, NULL);
```
### 3.7 I/O 模型对比
| 模型 | 阻塞 | 同步/异步 | 性能 |
|------|------|------------|------|
| 阻塞 I/O | 是 | 同步 | 低 |
| 非阻塞 I/O | 否 | 同步 | 中 |
| I/O 多路复用 | 是 | 同步 | 高 |
| 信号驱动 I/O | 否 | 同步 | 高 |
| 异步 I/O | 否 | 异步 | 最高 |
### 3.8 Nginx 使用的 I/O 模型
Nginx 默认使用 **Epoll**Linux**Kqueue**FreeBSD/macOS实现高效的事件驱动。
```
┌─────────────────────────────────────────────────────┐
│ Nginx 事件驱动架构 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Master Process │ │
│ │ 加载配置 │ 启动 Worker 进程 │ │
│ └──────────────────┬──────────────────────────┘ │
│ │ │
│ ┌──────────────────▼──────────────────────────┐ │
│ │ Worker 进程 │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Event Loop (Epoll/Kqueue) │ │ │
│ │ │ │ │ │
│ │ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │
│ │ │ │conn1│ │conn2│ │conn3│ ... │ │ │
│ │ │ └─────┘ └─────┘ └─────┘ │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘
```
---
## 4. Nginx 介绍和架构
### 4.1 Nginx 简介
NginxEngine X是一个高性能的 HTTP 服务器和反向代理服务器,由俄罗斯工程师 Igor Sysoev 开发。
### 4.2 Nginx 特点
| 特点 | 说明 |
|------|------|
| 高并发 | 轻量级,高并发连接(支持 5 万+ |
| 低内存 | 内存占用极低10MB/万连接) |
| 高可靠性 | 经过大量生产环境验证 |
| 热部署 | 不中断服务的情况下升级配置 |
| 模块化 | 丰富的官方和第三方模块 |
| 反向代理 | 支持 HTTP、HTTPS、TCP、UDP |
| 负载均衡 | 内置多种负载均衡策略 |
| 静态文件处理 | 高效的静态文件服务 |
### 4.3 Nginx 架构
```
┌─────────────────────────────────────────────────────┐
│ Nginx 架构 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ Master Process │ │
│ │ 读取/验证配置 │ 管理 Worker │ 信号处理 │ │
│ └─────────────────────┬──────────────────────┘ │
│ │ │
│ ┌─────────────────────▼──────────────────────┐ │
│ │ Worker Process多 worker │ │
│ │ │ │
│ │ ┌──────────────────────────────────────┐ │ │
│ │ │ Event Loop (Epoll) │ │ │
│ │ │ │ │ │
│ │ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │
│ │ │ │Request │ │ Request │ │Request │ │ │ │
│ │ │ │ Handler│ │ Handler │ │ Handler│ │ │ │
│ │ │ └────────┘ └────────┘ └────────┘ │ │ │
│ │ └──────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ Cache Manager/Loader │ │
│ └────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘
```
### 4.4 进程模型
```nginx
# nginx.conf
worker_processes auto; # Worker 进程数auto = CPU 核心数)
worker_cpu_affinity auto; # CPU 亲和性
worker_rlimit_nofile 65535; # 最大打开文件数
events {
worker_connections 10240; # 每个 worker 最大连接数
use epoll; # 使用 epoll 事件模型
multi_accept on; # 接受多个连接
}
```
### 4.5 模块体系
Nginx 采用模块化设计,核心模块和功能模块:
| 模块类型 | 示例 | 说明 |
|----------|------|------|
| 核心模块 | ngx_core | 核心功能 |
| 事件模块 | ngx_epoll_module | 事件处理 |
| HTTP 模块 | ngx_http_core | HTTP 处理 |
| 代理模块 | ngx_http_proxy | HTTP 反向代理 |
| 负载均衡 | ngx_http_upstream | 负载均衡 |
| 压缩模块 | ngx_http_gzip | 内容压缩 |
| SSL 模块 | ngx_http_ssl | HTTPS 支持 |
| 缓存模块 | ngx_http_proxy_cache | 响应缓存 |
| 日志模块 | ngx_http_log | 访问日志 |
### 4.6 工作流程
```
┌─────────────────────────────────────────────────────┐
│ Nginx 请求处理流程 │
├─────────────────────────────────────────────────────┤
│ │
│ 1. 接收请求 │
│ ↓ │
│ 2. HTTP 解析 │
│ ↓ │
│ 3. URI 匹配 location │
│ ↓ │
│ 4. 模块处理 │
│ ↓ │
│ 5. 过滤链处理 │
│ ↓ │
│ 6. 响应发送 │
│ │
└─────────────────────────────────────────────────────┘
```
### 4.7 配置结构
```nginx
# 全局块
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
# events 块
events {
worker_connections 10240;
}
# http 块
http {
# http 全局块
include /etc/nginx/mime.types;
default_type application/octet-stream;
# log 块
log_format main '$remote_addr - $remote_user $request '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# server 块
server {
listen 80;
server_name localhost;
# location 块
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api {
proxy_pass http://backend;
}
error_page 404 /404.html;
}
}
```
---
## 5. Nginx 安装
### 5.1 YUM 安装CentOS/RHEL
```bash
# 安装 EPEL 源
yum install epel-release -y
# 安装 Nginx
yum install nginx -y
# 启动服务
systemctl start nginx
systemctl enable nginx
# 检查状态
systemctl status nginx
# 测试访问
curl http://localhost
```
### 5.2 APT 安装Debian/Ubuntu
```bash
# 更新源
apt update
# 安装 Nginx
apt install nginx -y
# 启动服务
systemctl start nginx
systemctl enable nginx
# 检查版本
nginx -v
```
### 5.3 编译安装
```bash
# 安装依赖
yum install -y gcc make pcre pcre-devel zlib zlib-devel openssl openssl-devel
# 下载源码
wget https://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# 配置
./configure \
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module
# 编译安装
make -j4
make install
# 创建用户
useradd -M -s /sbin/nologin nginx
# 启动 Nginx
/usr/local/nginx/sbin/nginx
```
### 5.4 Docker 安装
```bash
# 拉取镜像
docker pull nginx:1.24
# 运行容器
docker run -d \
--name nginx \
-p 80:80 \
-p 443:443 \
-v /data/nginx/conf:/etc/nginx/conf \
-v /data/nginx/html:/usr/share/nginx/html \
-v /data/nginx/logs:/var/log/nginx \
nginx:1.24
# 测试配置
docker exec nginx nginx -t
```
### 5.5 目录结构
```bash
/usr/local/nginx/
├── sbin/ # 可执行文件
│ └── nginx
├── conf/ # 配置文件
│ ├── nginx.conf # 主配置文件
│ ├── fastcgi_params
│ ├── scgi_params
│ └── uwsgi_params
├── html/ # 默认网页
│ ├── index.html
│ └── 50x.html
└── logs/ # 日志目录
├── access.log
└── error.log
```
### 5.6 常用命令
```bash
# 检查配置文件
nginx -t
# 指定配置文件
nginx -t -c /path/to/nginx.conf
# 启动
nginx
# 重新加载配置
nginx -s reload
# 停止(快速)
nginx -s stop
# 优雅停止
nginx -s quit
# 重新打开日志
nginx -s reopen
# 查看版本
nginx -v
# 详细版本信息
nginx -V
# 发送信号
kill -s SIGTERM $(cat /var/run/nginx.pid)
kill -s SIGHUP $(cat /var/run/nginx.pid)
```
---
## 6. Nginx 各种模块实现 Web 服务
### 6.1 静态文件服务
```nginx
server {
listen 80;
server_name www.example.com;
# 根目录
root /usr/share/nginx/html;
# 默认文件
index index.html index.htm;
# 访问控制
location / {
allow 192.168.1.0/24;
deny all;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 缓存配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# 日志配置
access_log /var/log/nginx/www_access.log combined;
error_log /var/log/nginx/www_error.log;
}
```
### 6.2 目录浏览
```nginx
server {
listen 80;
server_name files.example.com;
location / {
root /data/files;
autoindex on; # 开启目录浏览
autoindex_exact_size on; # 显示精确大小
autoindex_localtime on; # 显示本地时间
charset utf-8; # 字符集
}
}
```
### 6.3 虚拟主机
```nginx
# 基于端口
server {
listen 80;
server_name _;
root /data/site1;
}
server {
listen 8080;
server_name _;
root /data/site2;
}
# 基于域名
server {
listen 80;
server_name www.site1.com;
root /data/site1;
}
server {
listen 80;
server_name www.site2.com;
root /data/site2;
}
```
### 6.4 HTTPS 配置
```nginx
server {
listen 443 ssl http2;
server_name www.example.com;
# 证书配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 协议和加密套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
# 会话复用
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
root /usr/share/nginx/html;
index index.html;
}
```
### 6.5 访问控制
```nginx
# IP 黑名单
location / {
deny 192.168.1.100;
deny 10.0.0.0/8;
allow all;
}
# 用户认证
location /admin {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# 防盗链
location ~* \.(jpg|jpeg|png|gif)$ {
valid_referers none blocked www.example.com;
if ($invalid_referer) {
return 403;
}
}
```
### 6.6 限流配置
```nginx
# 连接数限制
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
limit_conn addr 10;
}
# 请求速率限制
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location /api {
limit_req zone=one burst=20 nodelay;
}
}
# 带宽限制
location /download {
limit_rate 1m; # 限速 1MB/s
limit_rate_after 10m; # 前 10MB 不限速
}
```
### 6.7 Gzip 压缩
```nginx
http {
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml application/json
application/javascript application/xml application/xml+rss;
# 禁用老浏览器
gzip_disable "MSIE [1-6]\.";
}
```
### 6.8 请求重写
```nginx
# 重定向
server {
rewrite ^/old/(.*)$ /new/$1 permanent;
rewrite ^/redirect$ https://www.example.com permanent;
rewrite ^/temp$ https://www.example.com temporary;
}
# 条件重写
server {
if ($scheme != "https") {
return 301 https://$server_name$request_uri;
}
}
# 隐藏 PHP 扩展名
location / {
rewrite ^/([a-zA-Z0-9_-]+)\.php$ /$1 last;
}
```
### 6.9 状态监控
```nginx
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
# 返回示例
# Active connections: 2
# server accepts handled requests
# 10 10 100
# Reading: 0 Writing: 1 Waiting: 0
```
---
## 7. Nginx 实现 HTTP 负载均衡
### 7.1 负载均衡概述
Nginx 内置 Upstream 模块,支持多种负载均衡策略。
```
┌─────────────────────────────────────────────────────┐
│ Nginx 负载均衡架构 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ │
│ │ Client │ │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Nginx │ │
│ │ Upstream │ │
│ └──────┬───────┘ │
│ │ │
│ ┌────┼────┬──────┐ │
│ ▼ ▼ ▼ ▼ │
│ ┌────┐┌────┐┌────┐┌────┐ │
│ │ S1 ││ S2 ││ S3 ││ S4 │ Backend Servers │
│ └────┘└────┘└────┘└────┘ │
│ │
└─────────────────────────────────────────────────────┘
```
### 7.2 轮询负载均衡
```nginx
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
```
### 7.3 加权轮询
```nginx
upstream backend {
server 192.168.1.10:8080 weight=5;
server 192.168.1.11:8080 weight=3;
server 192.168.1.12:8080 weight=2;
}
```
### 7.4 IP 哈希
```nginx
upstream backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
```
### 7.5 最少连接
```nginx
upstream backend {
least_conn;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
```
### 7.6 最短响应时间
```nginx
upstream backend {
fair;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
```
### 7.7 Hash 一致性
```nginx
upstream backend {
hash $request_uri;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
```
### 7.8 健康检查
```nginx
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 down; # 标记为离线
server 192.168.1.13:8080 backup; # 备份服务器
}
```
### 7.9 完整示例
```nginx
http {
# 上游服务器组
upstream api_backend {
least_conn;
server 192.168.1.10:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 weight=2 max_fails=3 fail_timeout=30s;
keepalive 32; # 保持连接数
}
upstream static_backend {
server 192.168.1.20:80;
server 192.168.1.21:80;
}
# 代理 API
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://api_backend;
# 头部传递
proxy_http_version 1.1;
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_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 24k;
}
}
# 静态文件
server {
listen 80;
server_name static.example.com;
location / {
proxy_pass http://static_backend;
}
}
}
```
### 7.10 Lua 负载均衡
```lua
-- 使用 lua-resty-upstream 实现动态负载均衡
location / {
content_by_lua_block {
local upstream = require "resty.upstream"
local up = upstream:new({
name = "dynamic_backend",
servers = {
{ addr = "192.168.1.10", weight = 10 },
{ addr = "192.168.1.11", weight = 10 },
}
})
local server = up:select()
ngx.say(server)
}
}
```
---
## 8. Nginx 实现 TCP 反向代理
### 8.1 Stream 模块概述
Nginx 从 1.9.0 开始支持 TCP/UDP 反向代理,通过 `ngx_stream_module` 实现。
### 8.2 TCP 负载均衡
```nginx
stream {
# 日志配置
log_format basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
access_log /var/log/nginx/stream-access.log basic;
error_log /var/log/nginx/stream-error.log;
# TCP 上游服务器组
upstream mysql_backend {
least_conn;
server 192.168.1.10:3306 weight=5;
server 192.168.1.11:3306 weight=3;
server 192.168.1.12:3306 backup;
}
# TCP 代理配置
server {
listen 3306;
proxy_pass mysql_backend;
proxy_connect_timeout 10s;
proxy_timeout 3600s;
# TCP 相关配置
proxy_buffer_size 16k;
proxy_download_rate 0;
proxy_upload_rate 0;
}
# Redis 代理
upstream redis_backend {
server 192.168.1.20:6379;
server 192.168.1.21:6379;
}
server {
listen 6379;
proxy_pass redis_backend;
}
}
```
### 8.3 UDP 代理
```nginx
stream {
upstream dns_backend {
server 8.8.8.8:53;
server 8.8.4.4:53;
}
server {
listen 53 udd;
proxy_pass dns_backend;
# UDP 配置
proxy_responses 2;
proxy_timeout 10s;
}
}
```
### 8.4 TCP 健康检查
```nginx
stream {
# 简单健康检查
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
# 代理配置
server {
listen 8080;
proxy_connect_timeout 1s;
proxy_timeout 10s;
}
}
```
### 8.5 SNI 分离TCP 层)
```nginx
stream {
# 基于 SNI 的 TCP 代理
map $ssl_preread_server_name $backend {
www.example.com 192.168.1.10:443;
api.example.com 192.168.1.11:443;
default 192.168.1.20:443;
}
server {
listen 443;
ssl_preread on;
proxy_pass $backend;
}
}
```
---
## 9. Nginx 实现 FastCGI 反向代理
### 9.1 FastCGI 概述
FastCGI 是 Web 服务器与应用程序通信的协议Nginx 通过 `ngx_http_fastcgi_module` 实现。
### 9.2 PHP-FPM 配置
```nginx
server {
listen 80;
server_name www.example.com;
root /data/www;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP-FPM 代理
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 传递 FastCGI 参数
include fastcgi_params;
# 超时配置
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
# 缓冲配置
fastcgi_buffer_size 128k;
fastcgi_buffers 4 128k;
fastcgi_busy_buffers_size 256k;
fastcgi_max_temp_file_size 0;
}
# 拒绝访问隐藏文件
location ~ /\. {
deny all;
}
}
```
### 9.3 fastcgi_params 标准参数
```nginx
# 默认参数
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
```
### 9.4 FastCGI 缓存
```nginx
http {
# FastCGI 缓存配置
fastcgi_cache_path /tmp/fastcgi_cache levels=1:2
keys_zone=php_cache:10m
inactive=60m
max_size=1g;
server {
# 开启 FastCGI 缓存
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 启用缓存
fastcgi_cache php_cache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout http_500;
# 不缓存的请求
fastcgi_cache_bypass $http_cookie;
fastcgi_no_cache $http_cookie $http_authorization;
# 缓存 key
fastcgi_cache_key "$scheme$request_method$host$request_uri";
}
}
}
```
### 9.5 多 PHP-FPM 负载均衡
```nginx
upstream php_backend {
least_conn;
server 127.0.0.1:9000 weight=5;
server 127.0.0.1:9001 weight=3;
server 127.0.0.1:9002 backup;
}
server {
location ~ \.php$ {
fastcgi_pass php_backend;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
```
### 9.6 UWSGI 反向代理Python
```nginx
server {
listen 80;
server_name python.example.com;
location / {
uwsgi_pass 127.0.0.1:8000;
include uwsgi_params;
uwsgi_param SCRIPT_NAME /app;
uwsgi_param HOME /app;
uwsgi_param PYTHONPATH /app;
}
}
```
### 9.7 SCGI 反向代理
```nginx
server {
location / {
scgi_pass 127.0.0.1:9000;
include scgi_params;
scgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
```
---
## 10. Nginx 二次开发版
### 10.1 主流二次开发版
| 版本 | 说明 | 特点 |
|------|------|------|
| **Tengine** | 阿里巴巴开源 | 动态模块加载、组合SSI、内存优化 |
| **OpenResty** | 基于 Nginx + Lua | 强大的 Lua 脚本能力、高性能 API 网关 |
| **Apache** | 不适用 | 多进程模型 |
| **LiteSpeed** | 商业版本 | Apache 兼容、性能优异 |
### 10.2 Tengine
#### 10.2.1 Tengine 特点
- 继承 Nginx 所有特性
- 动态模块加载DSO
- 组合 SSIServer Side Include
- 内存优化:更低的内存占用
- 更好的负载均衡算法
- 更完善的监控和统计
#### 10.2.2 Tengine 安装
```bash
# 安装依赖
yum install gcc make zlib zlib-devel pcre pcre-devel openssl openssl-devel
# 下载 Tengine
wget https://tengine.taobao.org/download/tengine-2.3.3.tar.gz
tar -zxf tengine-2.3.3.tar.gz
cd tengine-2.3.3
# 编译安装
./configure --prefix=/usr/local/tengine
make -j4
make install
```
#### 10.2.3 Tengine 特有配置
```nginx
# 动态模块加载
load_module /usr/local/tengine/modules/ngx_http_upstream_consistent_hash_module.so;
# 组合 SSI
ssi on;
ssi_types text/html;
# 内存优化
tengine_worker_processes auto;
tengine_worker_rlimit_nofile 102400;
tengine_multi_accept on;
tengine_http_upstream_check_interval=5s;
tengine_http_upstream_check_timeout=2s;
```
### 10.3 OpenResty
#### 10.3.1 OpenResty 特点
- 基于 Nginx + LuaJIT
- 丰富的 Lua 库lua-resty-*
- 高性能 API 网关
- 实时请求处理
- 灵活的扩展能力
#### 10.3.2 OpenResty 安装
```bash
# 添加仓库CentOS 7
yum install yum-utils
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
# 安装
yum install openresty -y
# 启动
systemctl start openresty
```
#### 10.3.3 OpenResty 使用
```lua
-- hello.lua
ngx.say("Hello, OpenResty!")
-- nginx.conf
location /hello {
content_by_lua_file /usr/local/openresty/lua/hello.lua;
}
-- API 示例
location /api/user {
content_by_lua_block {
local cjson = require "cjson"
-- 获取请求参数
local args = ngx.req.get_uri_args()
-- 获取请求头
local headers = ngx.req.get_headers()
-- 响应
ngx.status = ngx.HTTP_OK
ngx.say(cjson.encode({
code = 0,
message = "success",
data = { user_id = args.id or "unknown" }
}))
ngx.exit(ngx.HTTP_OK)
}
}
```
#### 10.3.4 OpenResty 限流示例
```lua
-- rate_limit.lua
local limit = require("resty.limit.count")
-- 每分钟 100 次
local lim, err = limit.new("my_limit", 100, 60)
if not lim then
ngx.exit(500)
end
local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, true)
if not delay then
if err == "rejected" then
ngx.exit(429)
end
ngx.exit(500)
end
```
### 10.4 选择建议
| 场景 | 推荐版本 |
|------|----------|
| 传统 Web 服务 | Nginx 官方版 |
| 需要动态模块 | Tengine |
| API 网关/实时处理 | OpenResty |
| 需要 Lua 扩展 | OpenResty |
| 阿里系技术栈 | Tengine |
---
## 11. Nginx 高并发 Linux 内核优化
### 11.1 系统级优化
#### 11.1.1 文件描述符限制
```bash
# 修改系统限制
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf
# 重启生效
reboot
```
#### 11.1.2 网络连接优化
```bash
# /etc/sysctl.conf
# TCP 连接优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# TCP 连接回收
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
# TIME_WAIT 优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
# 内存优化
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 87380 16777216
# 生效配置
sysctl -p
```
### 11.2 Nginx 配置优化
```nginx
# /usr/local/nginx/conf/nginx.conf
# Worker 进程优化
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
# 事件处理优化
events {
worker_connections 10240;
use epoll;
multi_accept on;
}
# Gzip 压缩优化
gzip on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript;
# 连接复用
upstream backend {
server 192.168.1.10:8080;
keepalive 32; # 长连接数
}
server {
# 连接配置
keepalive_timeout 65;
keepalive_requests 1000;
# 缓冲区优化
client_body_buffer_size 128k;
client_max_body_size 50m;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
# 发送优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 缓冲写入
aio on;
directio 512;
}
```
### 11.3 完整优化配置示例
```nginx
# nginx.conf - 高性能配置
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 20480;
use epoll;
multi_accept on;
}
http {
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" '
'rt=$request_time uct=$upstream_connect_time '
'uht=$upstream_header_time urt=$upstream_response_time';
access_log /var/log/nginx/access.log main;
# 基础优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
# Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml application/json
application/javascript application/xml;
# 上游连接池
upstream backend {
server 192.168.1.10:8080 max_conns=1000;
server 192.168.1.11:8080 max_conns=1000;
keepalive 64;
}
# 代理配置
proxy_http_version 1.1;
proxy_set_header Connection "";
# 缓存配置
proxy_cache_path /tmp/nginx_cache
levels=1:2
keys_zone=api_cache:100m
inactive=60m
max_size=10g;
server {
listen 80;
server_name _;
location / {
proxy_pass http://backend;
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 8 64k;
}
}
}
# TCP 代理优化
stream {
log_format stream '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
access_log /var/log/nginx/stream.log stream;
upstream mysql {
least_conn;
server 192.168.1.20:3306 weight=5;
server 192.168.1.21:3306 weight=3;
keepalive 32;
}
server {
listen 3306;
proxy_pass mysql;
proxy_connect_timeout 5s;
proxy_timeout 3600s;
proxy_buffer_size 16k;
}
}
```
### 11.4 内核参数参考表
| 参数 | 默认值 | 推荐值 | 说明 |
|------|--------|--------|------|
| `fs.file-max` | 取决于系统 | 65535 | 系统最大文件数 |
| `net.core.somaxconn` | 128 | 65535 | socket 监听队列 |
| `net.core.netdev_max_backlog` | 1000 | 65535 | 网络设备队列 |
| `net.ipv4.tcp_max_syn_backlog` | 128 | 65535 | SYN 连接队列 |
| `net.ipv4.tcp_fin_timeout` | 60 | 30 | FIN_WAIT 超时 |
| `net.ipv4.tcp_keepalive_time` | 7200 | 1200 | 保活时间 |
| `net.ipv4.tcp_tw_reuse` | 0 | 1 | 复用 TIME_WAIT |
| `net.ipv4.ip_local_port_range` | 32768 60999 | 1024 65535 | 端口范围 |
### 11.5 性能监控
```bash
# 查看 Nginx 连接状态
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 查看 Nginx 进程数
ps -ef | grep nginx | wc -l
# 查看 Nginx 内存使用
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -n 10
# 查看 socket 统计
ss -s
# 查看 TCP 状态
cat /proc/net/snmp
# 查看连接数
curl http://localhost/nginx_status
```
---
## 附录
### 常用命令速查
| 命令 | 说明 |
|------|------|
| `nginx -t` | 测试配置 |
| `nginx -s reload` | 重新加载 |
| `nginx -s stop` | 停止 |
| `nginx -v` | 查看版本 |
| `nginx -V` | 详细版本信息 |
### 配置文件参数速查
| 参数 | 说明 |
|------|------|
| `worker_processes` | Worker 进程数 |
| `worker_connections` | 单 Worker 连接数 |
| `listen` | 监听端口 |
| `server_name` | 域名 |
| `proxy_pass` | 代理地址 |
| `root` | 根目录 |
| `index` | 默认文件 |
### 常用模块
| 模块 | 说明 |
|------|------|
| `ngx_http_core_module` | 核心模块 |
| `ngx_http_proxy_module` | HTTP 代理 |
| `ngx_http_upstream_module` | 负载均衡 |
| `ngx_http_rewrite_module` | URL 重写 |
| `ngx_http_gzip_module` | Gzip 压缩 |
| `ngx_http_ssl_module` | SSL/TLS |
| `ngx_stream_module` | TCP/UDP 代理 |
---
*文档创建时间2024年*