# 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 协议概述 HTTP(HyperText 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 │ │ │ │ 空行 │ │ │ │ 响应体: │ │ ... │ │ │ └─────────────────────────────────────────────────────┘ ``` ### 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/O(BIO) ``` ┌─────────────────────────────────────────────────────┐ │ 阻塞 I/O 模型 │ ├─────────────────────────────────────────────────────┤ │ │ │ 进程/线程 │ │ │ │ │ ▼ │ │ ┌─────────────┐ │ │ │ recv() │ ──→ 等待数据 │ │ │ 阻塞 │ ←── 数据到达 │ │ └─────────────┘ │ │ │ │ │ ▼ │ │ 处理数据 │ │ │ │ 特点:每个连接一个线程,资源消耗大 │ │ │ └─────────────────────────────────────────────────────┘ ``` ### 3.3 非阻塞 I/O(NIO) ``` ┌─────────────────────────────────────────────────────┐ │ 非阻塞 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/O(SIGIO) ```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/O(AI/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 简介 Nginx(Engine 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) - 组合 SSI(Server 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年*