小易说IT 小易说IT

Nginx 拆分目录结构完整配置范例

Nginx 拆分后目录结构(大型项目标准化)

/etc/nginx/
├── nginx.conf                # 主配置文件(全局、events、http公共段)
├── conf.d/
│   ├── site.conf             # 站点业务配置:server、upstream、反向代理、缓存、限流、防爬虫
│   └── map/
│       └── blackip.conf      # map定义:爬虫UA映射、IP黑名单geo配置
├── ssl/                      # 证书目录
│   ├── demo.example.com.crt
│   └── demo.example.com.key
└── html/                     # 自定义错误页面
    ├── 403.html
    ├── 404.html
    └── 5xx.html

原则:

  1. nginx.conf 只放全局公共配置,业务逻辑全部抽离到 conf.d

  2. map/geo 这类不能放在 server 块的配置单独放到 map/blackip.conf,在 http 段 include

  3. 多站点:新增 conf.d/another-site.conf 即可互不干扰

1. /etc/nginx/nginx.conf(主配置)

# 全局段
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
worker_rlimit_nofile 65535;

events {
    worker_connections  1024;
    use epoll;
    multi_accept on;
}

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;

    # ====================== 公共模块定义 ======================
    # 限流zone定义(必须在http顶层,不能放到server)
    limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
    limit_req_zone $binary_remote_addr zone=req_zone:10m rate=2r/s;

    # 代理缓存定义(必须在http顶层)
    proxy_cache_path /data/nginx/cache
                     levels=1:2
                     keys_zone=proxy_cache_zone:200m
                     inactive=7d
                     max_size=10g
                     use_temp_path=off;
    proxy_cache_key "$scheme$request_method$host$request_uri";
    proxy_cache_valid 200 302 10m;
    proxy_cache_valid 404 1m;
    proxy_cache_valid any 1s;

    # 安全响应头(全局)
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options nosniff;
    add_header Referrer-Policy "strict-origin-when-cross-origin";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # 引入 map / geo 黑名单配置
    include /etc/nginx/conf.d/map/blackip.conf;

    # 加载所有站点配置
    include /etc/nginx/conf.d/*.conf;
}

2. /etc/nginx/conf.d/map/blackip.conf(爬虫 UA 映射 + IP 黑名单 geo)

⚠️ 该文件只能被 include 在 http {} 顶层,不能放在 server 里面!

# IP静态黑名单
geo $blacklist_ip {
    default 0;
    # 在这里添加封禁IP
    192.168.1.100 1;
    10.0.0.55     1;
}

# 爬虫UA识别映射
map $http_user_agent $is_bot {
    default 0;
    ~*scraper|crawler|spider|bot|curl|wget|python-requests|phantomjs|selenium 1;
}

3. /etc/nginx/conf.d/site.conf(业务站点配置)

# 后端集群
upstream backend_server {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    keepalive 32;
}

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

# HTTPS 主站点
server {
    listen 443 ssl;
    server_name demo.example.com;

    ssl_certificate     /etc/nginx/ssl/demo.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/demo.example.com.key;
    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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # 黑名单IP拦截
    if ($blacklist_ip) {
        return 403;
    }

    # 爬虫UA拦截
    if ($is_bot) {
        return 403;
    }

    # 限流规则
    limit_conn conn_zone 10;
    limit_req zone=req_zone burst=5 nodelay;

    client_max_body_size 20M;

    # 代理缓存调试头,上线可注释
    add_header X-Cache $upstream_cache_status;

    # 主反向代理入口
    location / {
        proxy_pass http://backend_server;
        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 10s;
        proxy_read_timeout 30s;
        proxy_send_timeout 30s;

        proxy_cache proxy_cache_zone;
        # 登录态接口不缓存
        proxy_cache_bypass $cookie_session $http_authorization;
        proxy_no_cache $cookie_session $http_authorization;
    }

    # 静态资源:图片、js、css、字体
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|woff|ttf)$ {
        proxy_pass http://backend_server;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        expires 7d;
        add_header Cache-Control "public";
        proxy_cache proxy_cache_zone;
    }

    # 禁止访问隐藏文件 .开头
    location ~ /\. {
        deny all;
    }

    # 自定义错误页
    error_page 403 /403.html;
    error_page 404 /404.html;
    error_page 500 502 503 504 /5xx.html;
    location ~ ^/(403|404|5xx)\.html$ {
        root /usr/share/nginx/html;
        internal;
    }
}

部署操作脚本(直接复制执行)

# 创建缓存目录
mkdir -p /data/nginx/cache
chown nginx:nginx /data/nginx/cache
chmod 700 /data/nginx/cache

# 创建map目录
mkdir -p /etc/nginx/conf.d/map

# 配置校验
nginx -t

# 平滑重载
nginx -s reload

大型项目扩展说明

  1. 多站点:新增 conf.d/site2.conf,独立 upstream、server_name,共用全局限流 / 缓存 zone(如需独立限流,新建 limit_req_zone)

  2. 黑名单管理:blackip.conf 可单独维护,修改后 nginx -t && nginx -s reload 生效;量大推荐 OpenResty+Redis 动态拉黑,不用每次 reload

  3. 缓存独立隔离:多个业务要隔离缓存,新建 proxy_cache_path,每个站点使用独立 keys_zone

  4. 日志切割:配套 /etc/logrotate.d/nginx 日志轮转配置