Nginx 安装部署与常见调优配置

Nginx 安装部署与调优配置

系统环境:Ubuntu 22.04 LTS
Nginx 版本:1.24.x(Stable)


目录

  1. 安装 Nginx
  2. 目录结构说明
  3. 基础管理命令
  4. 虚拟主机配置
  5. HTTPS / SSL 配置
  6. 正向代理 vs 反向代理
  7. 反向代理配置
  8. 性能调优配置
  9. 安全加固配置
  10. 日志配置与切割
  11. 常见问题排查

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 隧道),生产中通常用 Squid3proxy 做正向代理。


反向代理

客户端 → 互联网 → 【反向代理 / 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

参考资料

posted @ 2026-05-29 16:05  陪你去流浪  阅读(36)  评论(0)    收藏  举报