Skip to content

Nginx

Nginx 是高性能的 Web 服务器和反向代理服务器,常用于静态资源托管、反向代理、负载均衡、HTTPS 终止等场景。

安装

sh
# Ubuntu / Debian
apt update && apt install nginx -y

# CentOS / RHEL / Rocky
yum install epel-release -y
yum install nginx -y

# 验证安装
nginx -v

服务管理

sh
systemctl start nginx       # 启动
systemctl stop nginx        # 停止
systemctl restart nginx     # 重启
systemctl reload nginx      # 重载配置(不停机)
systemctl enable nginx      # 开机自启
systemctl status nginx      # 查看状态

配置文件结构

/etc/nginx/
├── nginx.conf              # 主配置文件
├── sites-available/        # 站点配置(可用)
├── sites-enabled/          # 站点配置(启用,软链接到 sites-available)
├── conf.d/                 # 片段配置
└── modules-enabled/        # 模块配置

配置检查

修改配置后务必检查语法,避免 reload 失败导致服务中断:

sh
nginx -t               # 测试配置文件语法
nginx -T               # 测试并打印完整配置

核心配置详解

站点配置模板

nginx
server {
    # 监听端口
    listen 80;
    listen [::]:80;

    # 域名
    server_name example.com www.example.com;

    # 根目录
    root /var/www/example;
    index index.html index.htm;

    # 日志
    access_log /var/log/nginx/example_access.log;
    error_log  /var/log/nginx/example_error.log;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

反向代理

nginx
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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 30s;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}

负载均衡

nginx
upstream backend {
    # 负载均衡策略:轮询(默认)、ip_hash、least_conn、weight
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=2;
    server 192.168.1.12:8080 backup;   # 备用节点
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

负载均衡策略

策略说明
轮询(默认)依次分发,权重影响比例
least_conn分发到当前连接数最少的节点
ip_hash按客户端 IP 哈希,保证同一 IP 固定到同一节点
weight=N指定权重,权重越高分配越多

HTTPS / SSL

nginx
server {
    listen 443 ssl http2;
    server_name 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 ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    root /var/www/example;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

# HTTP 自动跳转 HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

申请 Let's Encrypt 证书

sh
# 安装 certbot
apt install certbot python3-certbot-nginx -y

# 自动申请并配置
certbot --nginx -d example.com -d www.example.com

# 续期(自动:systemd timer 默认已配置)
certbot renew --dry-run

URL 重写与重定向

nginx
server {
    # 域名跳转
    server_name old-domain.com;
    return 301 $scheme://new-domain.com$request_uri;

    # 路径重写
    location /old-path/ {
        rewrite ^/old-path/(.*)$ /new-path/$1 permanent;
    }

    # 去除 index.html
    location / {
        rewrite ^/(.*)\.html$ /$1 permanent;
        try_files $uri $uri.html $uri/ =404;
    }
}

访问控制

nginx
location /admin {
    # IP 白名单
    allow 192.168.1.0/24;
    allow 10.0.0.1;
    deny all;

    # 或使用密码认证
    auth_basic "Restricted Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

生成密码文件:

sh
apt install apache2-utils -y
htpasswd -c /etc/nginx/.htpasswd username

限流(Rate Limiting)

nginx
# 定义限流区域:每秒 1 请求,突发 5
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
    location /api/ {
        limit_req zone=one burst=5 nodelay;
        proxy_pass http://backend;
    }

    # 限制连接数
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    location /download/ {
        limit_conn addr 10;
    }
}

Gzip 压缩

nginx
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 256;
gzip_types
    text/plain
    text/css
    text/javascript
    application/javascript
    application/json
    application/xml
    image/svg+xml;

缓存静态资源

nginx
location /assets/ {
    expires 365d;
    add_header Cache-Control "public, immutable";

    # 关闭访问日志
    access_log off;
}

安全标头

nginx
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 Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

日志管理

sh
# 日志路径
/var/log/nginx/access.log
/var/log/nginx/error.log

# 日志格式自定义(nginx.conf 中定义)
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';

# 日志切割(使用 logrotate,系统默认已配置)
cat /etc/logrotate.d/nginx

性能优化

nginx
# 进程与连接
worker_processes auto;                      # 等于 CPU 核数
worker_connections 1024;                    # 单进程最大连接数
use epoll;                                  # Linux 高性能事件模型(默认)

# 发送文件
sendfile on;                                # 启用零拷贝
tcp_nopush on;                              # 优化数据包发送
tcp_nodelay on;

# 客户端限制
client_max_body_size 100m;                  # 上传文件大小限制
client_body_buffer_size 128k;

# 超时
keepalive_timeout 65;
keepalive_requests 100;
send_timeout 10;

故障排查

sh
# 检查配置
nginx -t

# 查看错误日志
tail -f /var/log/nginx/error.log

# 查看访问日志
tail -f /var/log/nginx/access.log

# 查看端口监听
ss -tlnp | grep nginx

# 测试域名解析
curl -I http://example.com

# 查看请求头
curl -I -H "Host: example.com" http://127.0.0.1

# 检查 systemd 日志
journalctl -u nginx -n 50

常见问题

问题原因解决
80 端口被占用Apache/httpd 等其他服务systemctl stop apache2 或修改 Nginx 端口
nginx -t 报错配置语法错误检查错误提示的行号,修正后重新测试
502 Bad Gateway后端服务未启动systemctl status 后端服务,确认服务正常运行
403 Forbidden目录权限不足chmod 755 /var/www/xxx,确认 index 文件存在
静态资源 404root 路径不对确认 rootalias 指向了正确的文件路径

蜀ICP备2025150039号