1882 lines
54 KiB
Markdown
1882 lines
54 KiB
Markdown
# 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 │
|
||
│ │
|
||
│ 空行 │
|
||
│ │
|
||
│ 响应体: │
|
||
│ <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/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年* |