203 lines
10 KiB
Markdown
203 lines
10 KiB
Markdown
|
|
```nginx
|
|||
|
|
user nginx;
|
|||
|
|
worker_processes 1;
|
|||
|
|
|
|||
|
|
error_log /var/log/nginx/error.log warn;
|
|||
|
|
pid /var/run/nginx.pid;
|
|||
|
|
|
|||
|
|
events {
|
|||
|
|
worker_connections 1024;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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"';
|
|||
|
|
|
|||
|
|
access_log /var/log/nginx/access.log main;
|
|||
|
|
|
|||
|
|
sendfile on;
|
|||
|
|
tcp_nopush on;
|
|||
|
|
tcp_nodelay on;
|
|||
|
|
keepalive_timeout 65;
|
|||
|
|
types_hash_max_size 2048;
|
|||
|
|
|
|||
|
|
# Gzip 压缩
|
|||
|
|
gzip on;
|
|||
|
|
gzip_vary on;
|
|||
|
|
gzip_proxied any;
|
|||
|
|
gzip_comp_level 6;
|
|||
|
|
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
|
|||
|
|
|
|||
|
|
server {
|
|||
|
|
listen 80;
|
|||
|
|
server_name localhost;
|
|||
|
|
|
|||
|
|
# 前端静态文件
|
|||
|
|
root /usr/share/nginx/html;
|
|||
|
|
index index.html;
|
|||
|
|
|
|||
|
|
# 前端路由支持
|
|||
|
|
location / {
|
|||
|
|
try_files $uri $uri/ /index.html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 后端 API 代理
|
|||
|
|
location /api/ {
|
|||
|
|
proxy_pass http://backend:8080;
|
|||
|
|
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;
|
|||
|
|
|
|||
|
|
# WebSocket 支持(如果需要)
|
|||
|
|
proxy_set_header Upgrade $http_upgrade;
|
|||
|
|
proxy_set_header Connection "upgrade";
|
|||
|
|
|
|||
|
|
# 超时设置
|
|||
|
|
proxy_connect_timeout 60s;
|
|||
|
|
proxy_send_timeout 60s;
|
|||
|
|
proxy_read_timeout 60s;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这是一个非常标准、功能完善、优化级别很高的 Nginx 配置,通常用于部署一个结合了**前端 SPA(单页应用)**和**后端 API**的现代 Web 应用。
|
|||
|
|
|
|||
|
|
我将从以下几个部分为您进行详细的解读:
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 整体结构与功能总结
|
|||
|
|
|
|||
|
|
**该配置的职责是:**
|
|||
|
|
|
|||
|
|
1. **作为反向代理(Reverse Proxy)**:它接收所有来自外部(`localhost:80`)的请求。
|
|||
|
|
2. **服务前端静态资源**:负责提供基于 `root` 目录的 HTML、CSS、JS 等文件,并支持前端路由(SPA)。
|
|||
|
|
3. **转发后端 API 请求**:将所有以 `/api/` 开头的请求,转发给指定的后端服务(`http://backend:8080`)。
|
|||
|
|
4. **优化性能**:通过设置 Gzip 压缩、HTTP 连接优化和定时器设置,确保传输效率。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 详细配置解读(按代码块)
|
|||
|
|
|
|||
|
|
### 1. 全局配置(Global Scope)
|
|||
|
|
|
|||
|
|
这部分设置了 Nginx 整个运行环境的参数。
|
|||
|
|
|
|||
|
|
| 指令 | 含义 | 作用和解释 |
|
|||
|
|
| :--- | :--- | :--- |
|
|||
|
|
| `user nginx;` | **用户权限** | 指定 Nginx 使用 `nginx` 系统用户来运行,这是最佳实践,避免使用 `root`。 |
|
|||
|
|
| `worker_processes 1;` | **工作进程** | 设置工作进程数量。`1` 表示使用单个进程。理想情况下,应设置为 `auto` 或 CPU 核数,以提高并发能力。 |
|
|||
|
|
| `error_log ... warn;` | **错误日志** | 配置错误日志路径和级别。`warn` 级别表示只记录警告及以上级别的错误。 |
|
|||
|
|
| `pid /var/run/nginx.pid;` | **进程ID文件** | 指定存储 Nginx 主进程 ID 的文件路径。 |
|
|||
|
|
| `events { ... }` | **事件处理** | 负责管理网络连接(Connection)。 |
|
|||
|
|
| `worker_connections 1024;` | **连接数限制** | 每个工作进程允许打开的最大并发连接数。1024 是一个常见的保守设置。 |
|
|||
|
|
|
|||
|
|
### 2. HTTP 块配置(`http` Block)
|
|||
|
|
|
|||
|
|
这块定义了所有 HTTP 服务通用的配置。
|
|||
|
|
|
|||
|
|
| 指令 | 含义 | 作用和解释 |
|
|||
|
|
| :--- | :--- | :--- |
|
|||
|
|
| `include /etc/nginx/mime.types;` | **文件类型包含** | 引入标准的 MIME 类型定义文件,使 Nginx 能够正确识别和发送文件的 Content-Type 头部。 |
|
|||
|
|
| `default_type application/octet-stream;` | **默认类型** | 如果无法确定文件类型,则默认将其视为二进制流。 |
|
|||
|
|
| `log_format main '...'` | **自定义日志格式** | 定义了访问日志的详细格式。它记录了请求来源 IP、时间、请求方式/路径、HTTP 状态码、传输字节数等,非常完整。 |
|
|||
|
|
| `access_log ... main;` | **访问日志** | 指定使用前面定义的 `main` 格式,并将访问记录写入 `/var/log/nginx/access.log`。 |
|
|||
|
|
| `sendfile on;` | **性能优化** | 启用 `sendfile` 功能,允许 Nginx 直接将内核缓冲区的内容发送给客户端,跳过用户空间的复制,极大地提升文件传输效率。 |
|
|||
|
|
| `tcp_nopush on;` | **性能优化** | 当发送多个数据包时,确保这些数据包被一次性发送,避免网络延迟和不必要的包分割。 |
|
|||
|
|
| `tcp_nodelay on;` | **性能优化** | 禁用发送数据包的缓冲机制,数据发送后立即离开,降低延迟,适用于需要低延迟的应用。 |
|
|||
|
|
| `keepalive_timeout 65;` | **连接保持** | 设置客户端与服务器保持空闲连接的最大秒数(这里是 65 秒)。 |
|
|||
|
|
| `gzip on;` | **压缩开启** | 启用 Gzip 压缩,减少传输数据量,提升速度。 |
|
|||
|
|
| `gzip_vary on;` | **缓存优化** | 当启用压缩后,所有响应头都必须包含 `Vary: Accept-Encoding`,确保缓存服务器不会错误地缓存未压缩或不同压缩级别的内容。 |
|
|||
|
|
| `gzip_proxied any;` | **压缩范围** | 无论请求是否来自代理,都进行压缩。 |
|
|||
|
|
| `gzip_types ...` | **压缩类型** | 列出需要被 Gzip 压缩的文件类型(如文本、JS、CSS、JSON)。 |
|
|||
|
|
|
|||
|
|
### 3. 服务器配置(`server` Block)
|
|||
|
|
|
|||
|
|
这部分定义了一个虚拟主机(Virtual Host),决定了 Nginx 在哪个端口和哪个域名上监听请求。
|
|||
|
|
|
|||
|
|
| 指令 | 含义 | 作用和解释 |
|
|||
|
|
| :--- | :--- | :--- |
|
|||
|
|
| `listen 80;` | **监听端口** | 表示该服务器实例监听所有进来的 HTTP 流量(端口 80)。 |
|
|||
|
|
| `server_name localhost;` | **虚拟域名** | 限制此配置只响应 `localhost` 的请求。 |
|
|||
|
|
|
|||
|
|
### 4. 路径匹配配置(`location` Blocks)
|
|||
|
|
|
|||
|
|
这是最核心的逻辑部分,决定了不同 URL 路径如何被处理。
|
|||
|
|
|
|||
|
|
#### 🅰️ 前端静态文件处理 (SPA 路由支持)
|
|||
|
|
|
|||
|
|
```nginx
|
|||
|
|
# 前端静态文件
|
|||
|
|
root /usr/share/nginx/html;
|
|||
|
|
index index.html;
|
|||
|
|
|
|||
|
|
# 前端路由支持
|
|||
|
|
location / {
|
|||
|
|
try_files $uri $uri/ /index.html;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
* **`root /usr/share/nginx/html;`**: 指定所有静态文件的根目录。
|
|||
|
|
* **`location /`**: 匹配所有路径(所有请求)。
|
|||
|
|
* **`try_files $uri $uri/ /index.html;`**: **这是支持单页应用(SPA)的关键指令。**
|
|||
|
|
1. **`$uri`**: Nginx 尝试从 `root` 目录查找请求的完整文件(例如:`/js/main.js`)。
|
|||
|
|
2. **`$uri/`**: 如果找不到文件,则尝试查找是否是请求的一个目录。
|
|||
|
|
3. **`/index.html`**: 如果前两者都失败(即,用户访问的是一个不存在的路径,但这个路径应该被 SPA 的前端路由接管,如 `/user/profile`),则内部重定向(Rewrite)请求到 `/index.html`。
|
|||
|
|
* **总结:** 确保所有的请求最终都会被 `index.html` 接收,让前端 JavaScript 框架(Vue/React/Angular)去判断路由,从而实现 SPA 的前端路由。
|
|||
|
|
|
|||
|
|
#### 🅱️ 后端 API 代理处理
|
|||
|
|
|
|||
|
|
```nginx
|
|||
|
|
location /api/ {
|
|||
|
|
proxy_pass http://backend:8080;
|
|||
|
|
# ... 其他配置 ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
* **`location /api/`**: 匹配所有以 `/api/` 开头的请求(例如:`/api/users`)。
|
|||
|
|
* **`proxy_pass http://backend:8080;`**: 这是核心代理指令。它将所有匹配的请求,转发到内部网络服务 `backend` 的 `8080` 端口。
|
|||
|
|
|
|||
|
|
**代理请求头设置 (Headers)**
|
|||
|
|
|
|||
|
|
这些指令至关重要,因为它们确保了后端服务(`backend`)能够获取到客户端的真实信息,而不是代理服务器本身的 IP 地址。
|
|||
|
|
|
|||
|
|
* `proxy_http_version 1.1;`: 强制代理使用 HTTP/1.1,确保高级特性(如 Connection 头)可用。
|
|||
|
|
* `proxy_set_header Host $host;`: 告诉后端服务客户端实际请求的 Host 名称。
|
|||
|
|
* `proxy_set_header X-Real-IP $remote_addr;`: 将客户端的真实 IP 地址传递给后端。
|
|||
|
|
* `proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;`: 记录所有代理跳过的 IP 地址链(用于安全审计和日志)。
|
|||
|
|
* `proxy_set_header X-Forwarded-Proto $scheme;`: 告知后端服务原始请求是通过 HTTP 还是 HTTPS 传输的。
|
|||
|
|
|
|||
|
|
**WebSocket 支持**
|
|||
|
|
|
|||
|
|
* `proxy_set_header Upgrade $http_upgrade;`
|
|||
|
|
* `proxy_set_header Connection "upgrade";`: 这两行代码是专门为了支持 **WebSocket** 连接的。WebSocket 需要特殊的 HTTP 升级(Upgrade)头,用于从传统的 HTTP 长连接模式切换到双向的 WS 协议。
|
|||
|
|
|
|||
|
|
**超时设置**
|
|||
|
|
|
|||
|
|
* `proxy_connect_timeout 60s;`:连接后端服务时等待的最大时间。
|
|||
|
|
* `proxy_send_timeout 60s;`:将请求发送给后端时等待的最大时间。
|
|||
|
|
* `proxy_read_timeout 60s;`:从后端服务读取响应数据时等待的最大时间。
|
|||
|
|
* **目的:** 将所有超时设置设置为 60 秒,确保即使后端处理耗时较长(比如复杂的报告生成),Nginx也不会提前中断连接。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🌟 总结与最佳实践点
|
|||
|
|
|
|||
|
|
1. **职责分离完美体现:** 通过 `location /api/` 和 `location /` 的隔离,Nginx完美地将“站内服务(静态资源)”和“后端数据服务(API)”分离,使得架构清晰。
|
|||
|
|
2. **性能优化到位:** 包含了 `sendfile`、`tcp_nopush`、`tcp_nodelay` 以及 `gzip` 等一系列优化,配置的性能起点很高。
|
|||
|
|
3. **健壮性高:** `try_files` 的使用确保了即使是客户端路径错误,应用也能重定向到根页面,避免出现“文件找不到”的错误,保证了用户体验。
|
|||
|
|
4. **反向代理标准配置:** 后端代理部分的配置(特别是 `X-Real-IP` 和 `X-Forwarded-*` 头)是所有企业级反向代理的标配,非常专业。
|
|||
|
|
|
|||
|
|
**建议改进点(如果适用):**
|
|||
|
|
|
|||
|
|
1. **Worker Processes:** 如果部署在服务器上,建议将 `worker_processes 1;` 改为 `worker_processes auto;` 或根据 CPU 核数设置,以充分利用服务器性能。
|
|||
|
|
2. **HTTPS/SSL:** 实际生产环境中,`server` 块应该增加 `listen 443 ssl;`,并在其中配置 SSL 证书,确保所有的通信都是加密的。
|