摘要:本文详细介绍 Nginx 在生产环境中的部署实战,涵盖前端应用部署、后端服务代理、数据库管理、监控告警和故障排查。通过本文档,你将掌握 Nginx 在生产环境中的最佳实践,能够独立完成完整的部署流程。
关键词:Nginx、部署实战、前端部署、后端代理、数据库、监控、故障排查
适合人群:有 Nginx 基础的开发者、运维工程师、想学习生产环境部署的工程师
阅读时间:约 50 分钟
版本信息:Nginx 1.24+ | 支持 Linux/Windows/macOS
文章目录
- [1. 前端应用部署](#1. 前端应用部署)
-
- [1.1 Vue/React 单页应用](#1.1 Vue/React 单页应用)
- [1.2 多环境部署](#1.2 多环境部署)
- [1.3 静态网站部署](#1.3 静态网站部署)
- [2. 后端服务代理](#2. 后端服务代理)
-
- [2.1 Node.js 服务代理](#2.1 Node.js 服务代理)
- [2.2 Python 服务代理](#2.2 Python 服务代理)
- [2.3 Java 服务代理](#2.3 Java 服务代理)
- [2.4 PHP 服务代理](#2.4 PHP 服务代理)
- [3. WebSocket 代理](#3. WebSocket 代理)
- [4. 数据库管理](#4. 数据库管理)
-
- [4.1 MySQL 代理](#4.1 MySQL 代理)
- [4.2 Redis 代理](#4.2 Redis 代理)
- [5. 监控告警](#5. 监控告警)
-
- [5.1 Nginx 状态监控](#5.1 Nginx 状态监控)
- [5.2 Prometheus 监控](#5.2 Prometheus 监控)
- [5.3 日志监控](#5.3 日志监控)
- [6. 故障排查](#6. 故障排查)
-
- [6.1 常见问题排查](#6.1 常见问题排查)
-
- [问题 1:Nginx 无法启动](#问题 1:Nginx 无法启动)
- [问题 2:502 Bad Gateway](#问题 2:502 Bad Gateway)
- [问题 3:404 Not Found](#问题 3:404 Not Found)
- [问题 4:504 Gateway Timeout](#问题 4:504 Gateway Timeout)
- [6.2 性能排查](#6.2 性能排查)
- [6.3 日志分析](#6.3 日志分析)
- [7. 实战案例](#7. 实战案例)
-
- [实战 1:完整的前后端分离部署](#实战 1:完整的前后端分离部署)
- [实战 2:微服务网关部署](#实战 2:微服务网关部署)
- [实战 3:文件上传服务器](#实战 3:文件上传服务器)
- [8. 常见问题 FAQ](#8. 常见问题 FAQ)
- [9. 学习资源与建议](#9. 学习资源与建议)
1. 前端应用部署
1.1 Vue/React 单页应用
部署 Vue/React 等单页应用(SPA)需要特殊配置支持前端路由:
nginx
server {
listen 80;
server_name example.com;
# 前端构建目录
root /var/www/my-app/dist;
index index.html;
# SPA 路由支持
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# HTML 文件不缓存
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# 后端 API 代理
location /api {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
配置说明:
try_files $uri $uri/ /index.html:如果文件不存在,返回 index.html(支持前端路由)- 静态资源缓存 1 年(文件名带 hash)
- HTML 文件不缓存(确保获取最新版本)
1.2 多环境部署
同一服务器部署多个环境:
nginx
# 生产环境
server {
listen 80;
server_name prod.example.com;
root /var/www/prod/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
# 测试环境
server {
listen 80;
server_name test.example.com;
root /var/www/test/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
# 开发环境
server {
listen 80;
server_name dev.example.com;
root /var/www/dev/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
1.3 静态网站部署
部署纯静态网站(HTML/CSS/JS):
nginx
server {
listen 80;
server_name static.example.com;
root /var/www/static-site;
index index.html;
# Gzip 压缩
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_types text/plain text/css application/json application/javascript text/xml;
# 静态资源缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 默认匹配
location / {
try_files $uri $uri/ =404;
}
}
2. 后端服务代理
2.1 Node.js 服务代理
代理 Node.js 后端服务:
nginx
upstream node_backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
# Gzip 压缩
gzip on;
gzip_types application/json text/plain;
location / {
proxy_pass http://node_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}
2.2 Python 服务代理
代理 Python 后端服务(Flask/FastAPI):
nginx
upstream python_backend {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://python_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
2.3 Java 服务代理
代理 Java 后端服务(Spring Boot):
nginx
upstream java_backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
# 大文件上传
client_max_body_size 50m;
location / {
proxy_pass http://java_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 超时设置(Java 服务可能需要更长时间)
proxy_connect_timeout 120s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
}
}
2.4 PHP 服务代理
代理 PHP 服务(PHP-FPM):
nginx
server {
listen 80;
server_name php.example.com;
root /var/www/php-app;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
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;
}
}
3. WebSocket 代理
3.1 基础 WebSocket 代理
配置 WebSocket 代理:
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket_backend {
server 127.0.0.1:3000;
}
server {
listen 80;
server_name ws.example.com;
location /ws {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 超时设置(WebSocket 需要更长时间)
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
3.2 Socket.IO 代理
配置 Socket.IO 代理:
nginx
upstream socketio_backend {
ip_hash; # 会话保持
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
listen 80;
server_name socketio.example.com;
location /socket.io/ {
proxy_pass http://socketio_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
💡 提示 :Socket.IO 必须使用
ip_hash或会话保持,否则长连接可能断开。
4. 数据库管理
4.1 MySQL 代理
使用 Nginx 代理 MySQL 连接(不推荐,但可行):
nginx
stream {
upstream mysql_backend {
server 127.0.0.1:3306;
}
server {
listen 3307;
proxy_pass mysql_backend;
}
}
💡 提示:数据库代理通常使用专业的代理工具(如 ProxySQL、MaxScale),Nginx 更适合 HTTP 代理。
4.2 Redis 代理
使用 Nginx 代理 Redis 连接:
nginx
stream {
upstream redis_backend {
server 127.0.0.1:6379;
}
server {
listen 6380;
proxy_pass redis_backend;
}
}
💡 提示 :
stream块用于 TCP/UDP 代理,与http块平级。
5. 监控告警
5.1 Nginx 状态监控
启用 Nginx 状态监控模块:
nginx
http {
# 启用状态监控
server {
listen 80;
server_name status.example.com;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
}
}
访问状态:
bash
curl http://status.example.com/nginx_status
输出说明:
Active connections: 123
server accepts handled requests
12345 12345 67890
Reading: 1 Writing: 2 Waiting: 120
| 指标 | 说明 |
|---|---|
| Active connections | 当前活跃连接数 |
| accepts | 已接受的连接数 |
| handled | 已处理的连接数 |
| requests | 已处理的请求数 |
| Reading | 正在读取请求头的连接数 |
| Writing | 正在发送响应的连接数 |
| Waiting | 等待请求的空闲连接数 |
5.2 Prometheus 监控
使用 Prometheus 监控 Nginx:
nginx
# 安装 nginx-exporter
# https://github.com/nginxinc/nginx-prometheus-exporter
# 启动 exporter
nginx-prometheus-exporter -nginx.scrape-uri http://localhost/nginx_status
Prometheus 配置:
yaml
scrape_configs:
- job_name: 'nginx'
static_configs:
- targets: ['localhost:9113']
5.3 日志监控
使用 ELK 栈监控 Nginx 日志:
nginx
http {
# JSON 格式日志(便于 ELK 解析)
log_format json escape=json '{'
'"time": "$time_local",'
'"remote_addr": "$remote_addr",'
'"request": "$request",'
'"status": "$status",'
'"body_bytes_sent": "$body_bytes_sent",'
'"http_referer": "$http_referer",'
'"http_user_agent": "$http_user_agent",'
'"request_time": "$request_time",'
'"upstream_response_time": "$upstream_response_time"'
'}';
access_log /var/log/nginx/access.log json;
}
6. 故障排查
6.1 常见问题排查
问题 1:Nginx 无法启动
bash
# 检查配置文件语法
nginx -t
# 查看错误日志
tail -f /var/log/nginx/error.log
# 检查端口占用
netstat -tlnp | grep :80
# 检查权限
ls -l /var/log/nginx/
问题 2:502 Bad Gateway
bash
# 检查后端服务是否运行
curl http://localhost:3000
# 检查 Nginx 错误日志
tail -f /var/log/nginx/error.log
# 检查防火墙
sudo ufw status
问题 3:404 Not Found
bash
# 检查文件是否存在
ls -l /var/www/html/index.html
# 检查 root 路径配置
cat /etc/nginx/nginx.conf
# 检查权限
chmod 755 /var/www/html
chown -R www-data:www-data /var/www/html
问题 4:504 Gateway Timeout
nginx
# 增加超时时间
location / {
proxy_connect_timeout 120s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
}
6.2 性能排查
bash
# 查看当前连接数
netstat -n | grep :80 | wc -l
# 查看各状态连接数
netstat -n | grep :80 | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 查看 Nginx 进程
ps aux | grep nginx
# 查看系统负载
top
htop
6.3 日志分析
bash
# 查看最近 100 条错误日志
tail -n 100 /var/log/nginx/error.log
# 查看最近 100 条访问日志
tail -n 100 /var/log/nginx/access.log
# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 统计 IP 访问次数
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 统计慢请求(响应时间 > 1s)
awk '$NF > 1 {print}' /var/log/nginx/access.log
7. 实战案例
实战 1:完整的前后端分离部署
nginx
worker_processes auto;
worker_cpu_affinity auto;
events {
worker_connections 2048;
use epoll;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# Gzip 压缩
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# 限流配置
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=20r/s;
# 后端服务器
upstream backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 32;
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS 服务器
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 前端静态文件
root /var/www/my-app/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 后端 API 代理
location /api {
limit_req zone=api_limit burst=50 nodelay;
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 日志
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
}
}
项目知识点:
- 工作进程优化
- Gzip 压缩
- 限流配置
- HTTPS 配置
- 安全头配置
- 静态资源缓存
- 反向代理
实战 2:微服务网关部署
nginx
upstream user_service {
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
upstream order_service {
server 127.0.0.1:4001;
server 127.0.0.1:4002;
}
upstream product_service {
server 127.0.0.1:5001;
server 127.0.0.1:5002;
}
server {
listen 80;
server_name gateway.example.com;
# 用户服务
location /api/users {
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 订单服务
location /api/orders {
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 商品服务
location /api/products {
proxy_pass http://product_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
实战 3:文件上传服务器
nginx
server {
listen 80;
server_name upload.example.com;
client_max_body_size 100m;
location /upload {
root /var/www/uploads;
client_body_rate 1m;
client_body_timeout 120s;
}
location /download {
root /var/www/uploads;
limit_rate 500k;
}
}
8. 常见问题 FAQ
Q1:如何查看 Nginx 是否启动成功?
A:使用以下命令:
bash
# 查看进程
ps aux | grep nginx
# 查看端口
netstat -tlnp | grep :80
# 查看错误日志
tail -f /var/log/nginx/error.log
Q2:如何平滑重启 Nginx?
A:按以下步骤操作:
bash
# 1. 测试配置语法
nginx -t
# 2. 平滑重启
nginx -s reload
Q3:如何配置 HTTPS?
A:使用 Let's Encrypt 免费证书:
bash
# 安装 certbot
sudo apt install certbot python3-certbot-nginx
# 获取证书
sudo certbot --nginx -d example.com
Q4:如何限制上传文件大小?
A:使用 client_max_body_size:
nginx
server {
client_max_body_size 10m; # 最大 10MB
}
Q5:如何配置跨域?
A:使用 add_header:
nginx
location /api {
add_header Access-Control-Allow-Origin "https://example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type, Accept" always;
if ($request_method = 'OPTIONS') {
return 204;
}
}
9. 学习资源与建议
学习建议
1. 先掌握基础,再学习实战 :确保理解基础配置后再进行实战部署
2. 多查看官方文档 :官方文档是最权威的资料
3. 善用测试命令 :每次修改配置后,先用 nginx -t 测试语法
4. 查看日志排错 :遇到问题时,查看错误日志是最快的排错方法
5. 使用版本控制:配置文件使用 Git 管理,方便回滚和对比
官方资源
- Nginx 官方文档
- Nginx 部署指南
- Let's Encrypt - 免费 SSL 证书
- Prometheus - 监控系统