Nginx 安装部署与常见调优配置
Nginx 安装部署与调优配置
系统环境:Ubuntu 22.04 LTS
Nginx 版本:1.24.x(Stable)
目录
1. 安装 Nginx
!!!下载压缩包二进制部署最方便
方式一:APT 官方源(推荐,版本较新)
# 安装依赖
sudo apt update
sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
# 导入官方签名密钥
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg > /dev/null
# 添加 Nginx 稳定版源
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
# 设置优先级(高于系统源)
echo -e "Package: *\nPin: origin nginx.org\nPin-Priority: 900\n" \
| sudo tee /etc/apt/preferences.d/99nginx
# 安装
sudo apt update
sudo apt install -y nginx
# 验证版本
nginx -v
方式二:Ubuntu 系统源(版本稍旧)
sudo apt update
sudo apt install -y nginx
设置开机自启
sudo systemctl enable nginx
sudo systemctl start nginx
sudo systemctl status nginx
防火墙放行
# 查看可用规则
sudo ufw app list
# 只开放 HTTP / HTTPS
sudo ufw allow 'Nginx Full'
# 或单独开放
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
2. 目录结构说明
/etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/ # 全局附加配置(*.conf 自动加载)
├── sites-available/ # 虚拟主机配置(未启用)
├── sites-enabled/ # 虚拟主机配置(软链接启用)
├── snippets/ # 可复用配置片段
├── mime.types # MIME 类型映射
└── fastcgi_params # FastCGI 参数
/var/www/html/ # 默认网站根目录
/var/log/nginx/ # 日志目录
├── access.log
└── error.log
/var/cache/nginx/ # 缓存目录
/run/nginx.pid # PID 文件
3. 基础管理命令
# 启动 / 停止 / 重启 / 重载
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx # 不中断连接热重载配置
# 测试配置文件语法
sudo nginx -t
sudo nginx -T # 输出完整合并后的配置
# 查看进程
ps aux | grep nginx
# 查看监听端口
sudo ss -tlnp | grep nginx
4. 虚拟主机配置
静态网站示例
sudo nano /etc/nginx/conf.d/example.com.conf
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
# 访问日志
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log warn;
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
}
# 创建网站目录
sudo mkdir -p /var/www/example.com/html
sudo chown -R www-data:www-data /var/www/example.com
# 测试并重载
sudo nginx -t && sudo systemctl reload nginx
5. HTTPS / SSL 配置
不在重复,openssl 自签证书有讲,实际生产需要到浏览器官方认证的签发机构
手动 SSL 配置示例(已有证书)
server {
listen 80;
server_name example.com www.example.com;
# HTTP 强制跳转 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# 证书路径
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# SSL 协议与加密套件(Mozilla 推荐 Intermediate)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# Session 复用(提升性能)
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s;
resolver_timeout 5s;
# HSTS(谨慎开启,确认 HTTPS 稳定后再启用)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
6. 正向代理 vs 反向代理
一句话理解
| 代理的是谁 | 谁知道有代理 | |
|---|---|---|
| 正向代理 | 替客户端出去请求 | 服务器不知道真实客户端 |
| 反向代理 | 替服务器接收请求 | 客户端不知道背后有多少服务器 |
正向代理
客户端 → 【正向代理】 → 互联网 / 目标服务器
客户端主动配置代理,让代理帮自己去访问外部资源。
典型用途:
- 访问外部网络(VPN)
- 企业内网统一出口,过滤员工访问的网站
- 缓存外部资源,节省带宽(如 npm/pip 私有镜像源)
Nginx 本身对正向代理支持有限(不支持 HTTPS CONNECT 隧道),生产中通常用 Squid 或 3proxy 做正向代理。
反向代理
客户端 → 互联网 → 【反向代理 / Nginx】 → 后端服务器集群
客户端不感知后端,只与 Nginx 打交道,由 Nginx 转发给真正的服务。
典型用途:
- 隐藏后端:客户端只看到 Nginx 的 IP,后端服务不暴露
- 负载均衡:把请求分发给多台服务器,提升并发能力
- SSL 卸载:Nginx 统一处理 HTTPS,后端只跑 HTTP,省去证书管理
- 统一入口:一个域名下
/api转发 Node.js、/static转发 CDN 等 - 缓存加速:Nginx 缓存后端响应,减轻后端压力
核心区别一图流
【正向代理】
你(客户端) → VPN/代理 → Google(服务器)
服务器看到的来源是代理 IP,不知道是你
【反向代理】
你(客户端) → Nginx → App Server 1
→ App Server 2
你只知道 Nginx 的地址,不知道背后有几台服务器
7. 反向代理配置
代理到本地应用(如 Node.js / Python)
upstream app_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 app.example.com;
location / {
proxy_pass http://app_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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; # WebSocket 支持
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲设置
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 8 64k;
}
}
负载均衡策略
upstream backend {
# 轮询(默认)
server 10.0.0.1:8080;
server 10.0.0.2:8080;
# 加权轮询
# server 10.0.0.1:8080 weight=3;
# server 10.0.0.2:8080 weight=1;
# IP Hash(会话保持)
# ip_hash;
# server 10.0.0.1:8080;
# server 10.0.0.2:8080;
# 最少连接
# least_conn;
# server 10.0.0.1:8080;
# server 10.0.0.2:8080;
# 备用服务器
server 10.0.0.3:8080 backup;
}
7. 性能调优配置
主配置 /etc/nginx/nginx.conf
# ============================================================
# 全局块
# ============================================================
user www-data;
# worker 进程数:通常设为 CPU 核心数,auto 自动检测
worker_processes auto;
# 绑定 worker 到 CPU(减少上下文切换)
worker_cpu_affinity auto;
# 每个 worker 最大打开文件数(需与系统 ulimit 一致)
worker_rlimit_nofile 65535;
pid /run/nginx.pid;
# ============================================================
# events 块
# ============================================================
events {
# 每个 worker 最大并发连接数
worker_connections 10240;
# 推荐在 Linux 下使用 epoll
use epoll;
# 一次性接受所有新连接(高并发场景开启)
multi_accept on;
}
# ============================================================
# http 块
# ============================================================
http {
# ---------- 基础 ----------
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 隐藏版本号(安全)
server_tokens off;
# ---------- 文件传输 ----------
sendfile on; # 零拷贝传输
tcp_nopush on; # 与 sendfile 配合,批量发送响应头
tcp_nodelay on; # 降低小包延迟(与 tcp_nopush 互补)
# ---------- 连接超时 ----------
keepalive_timeout 65;
keepalive_requests 1000; # 单连接最多复用次数
client_header_timeout 15s;
client_body_timeout 15s;
send_timeout 30s;
# ---------- 请求体大小限制 ----------
client_max_body_size 50m;
client_body_buffer_size 128k;
client_header_buffer_size 4k;
large_client_header_buffers 4 16k;
# ---------- Gzip 压缩 ----------
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5; # 1~9,越高 CPU 消耗越大,推荐 4~6
gzip_min_length 1024; # 小于 1KB 的响应不压缩
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types
text/plain text/css text/xml text/javascript
application/json application/javascript application/xml
application/rss+xml image/svg+xml font/woff2;
# ---------- 文件缓存 ----------
open_file_cache max=10000 inactive=30s;
open_file_cache_valid 60s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# ---------- 日志 ----------
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct=$upstream_connect_time '
'uht=$upstream_header_time urt=$upstream_response_time';
access_log /var/log/nginx/access.log main buffer=16k flush=5s;
error_log /var/log/nginx/error.log warn;
include /etc/nginx/conf.d/*.conf;
}
系统内核调优(/etc/sysctl.conf)
sudo nano /etc/sysctl.conf
# TCP 连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 文件描述符上限
fs.file-max = 2097152
# TIME_WAIT 优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# TCP 接收/发送缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 端口范围扩大
net.ipv4.ip_local_port_range = 1024 65535
# 使生效
sudo sysctl -p
系统资源限制(/etc/security/limits.conf)
www-data soft nofile 65535
www-data hard nofile 65535
8. 安全加固配置
# 可放入 /etc/nginx/snippets/security-headers.conf 复用
# 在 server 块中 include snippets/security-headers.conf;
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 防 XSS
add_header X-XSS-Protection "1; mode=block" always;
# 禁止 MIME 嗅探
add_header X-Content-Type-Options "nosniff" always;
# Referrer 策略
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# CSP(按需调整)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
# 隐藏 Server 头
server_tokens off;
more_clear_headers Server; # 需安装 ngx_headers_more 模块
限速(防爬虫 / CC 攻击)
# 在 http 块定义限速区域
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=20r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
# ...
location / {
limit_req zone=req_limit burst=50 nodelay;
limit_conn conn_limit 20;
# 超限返回 429
limit_req_status 429;
limit_conn_status 429;
}
}
禁止非法 HTTP 方法
location / {
# 只允许 GET / POST / HEAD
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 405;
}
}
9. 日志配置与切割
logrotate 配置(系统默认已包含)
cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
实时查看日志
# 实时访问日志
sudo tail -f /var/log/nginx/access.log
# 只看错误
sudo tail -f /var/log/nginx/error.log
# 统计 TOP IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
10. 常见问题排查
| 现象 | 排查步骤 |
|---|---|
| 502 Bad Gateway | 检查后端服务是否运行;检查 proxy_pass 地址端口;查看 error.log |
| 413 Request Entity Too Large | 增大 client_max_body_size |
| 504 Gateway Timeout | 增大 proxy_read_timeout / proxy_send_timeout |
| 403 Forbidden | 检查目录权限 ls -la;确认 root 路径;检查 SELinux/AppArmor |
| Nginx 无法启动 | sudo nginx -t 检查配置;journalctl -xe 查看日志;检查端口占用 ss -tlnp |
| 高并发下 CPU 飙升 | 检查 worker_processes;开启 epoll;检查是否有慢查询日志 |
| 静态文件不更新 | 检查浏览器缓存;确认 expires 配置;etag on; |
常用排查命令
# 查看 Nginx 主进程 PID 及 worker 数
ps aux | grep nginx
# 查看 Nginx 实时连接状态(需开启 stub_status)
curl http://127.0.0.1/nginx_status
# 开启 stub_status(监控用)
# location /nginx_status {
# stub_status;
# allow 127.0.0.1;
# deny all;
# }
# 查看当前连接数
ss -s
# 检查配置后平滑重载
sudo nginx -t && sudo systemctl reload nginx
附:Nginx 配置文件快速模板
# 新建站点一键脚本
DOMAIN="example.com"
sudo mkdir -p /var/www/${DOMAIN}/html
sudo chown -R www-data:www-data /var/www/${DOMAIN}
sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/${DOMAIN}.conf
sudo nano /etc/nginx/conf.d/${DOMAIN}.conf
sudo nginx -t && sudo systemctl reload nginx
参考资料

浙公网安备 33010602011771号