跳转至

Nginx

只保留实际会用到的配置要点与真实站点实例,通用理论请直接问 AI。

🟢常用命令

nginx -t          # 检查配置
nginx -T          # 打印最终生效配置
nginx -s reload   # 热加载
nginx -s quit     # 平稳关闭

🟢location 与 rewrite

= · ^~ · ~* · last · break · try_files。匹配优先级、rewrite 标志及 root/alias/try_files

flowchart TD
    A[请求 URI] --> B{"= 精确匹配?"}
    B -- 命中 --> Z[选用该 location]
    B -- 否 --> C{"^~ 前缀匹配?"}
    C -- 命中 --> Z
    C -- 否 --> D{"正则 ~ / ~*?"}
    D -- 命中 --> Z
    D -- 否 --> E[最长前缀匹配 / 兜底]
    E --> Z
location 匹配
location = / {                    # 完全匹配,优先级最高
location ^~ /images/ {            # 前缀匹配,命中后不再找正则
location ~* \.(gif|jpg)$ {        # 正则,~* 忽略大小写
location / {                      # 前缀匹配兜底

优先级:= > 完整路径 > ^~ > 正则 > 部分起始路径 > /

rewrite ^/users/(.*)$ /show?user=$1 break;
标志 行为
last 重新匹配 location
break 跳出当前 location
redirect 302 临时重定向
permanent 301 永久重定向
  • root:路径与 URI 叠加;alias:只取定义路径,末尾必须带 /,只能位于 location。
  • try_files $uri $uri.html @other;:依次找文件,都不存在时走最后一个(可为命名 location 或 =502)。

🟢反向代理

location / {
    proxy_set_header Host $host;                             # 避免 ssl 握手失败
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_pass http://127.0.0.1:8000;
}
指令 说明
proxy_connect_timeout 5s 连接超时,上传大文件时可放大
proxy_read_timeout 15 读取响应超时
client_max_body_size 10m 上传大小上限
proxy_hide_header Server 隐藏后端服务器信息

🟢负载均衡

ip_hash · least_conn · weight · max_fails · backupupstream 算法与健康检查。

upstream
upstream backend {
    ip_hash;                                    # 会话保持(大量用户共用 NAT IP 时可改用 sticky)
    server 172.16.100.103:8080 weight=1 max_fails=2;
    server 172.16.100.104:8080 weight=1 max_fails=2;
    server backup.example.com backup;           # 备用
}
算法 说明
rr 默认轮询,权重越大分配越多
ip_hash 同 IP 固定后端,解决 session
least_conn 最少活动连接
hash $key 自定义散列

HTTP 后端持久连接

需同时设置 proxy_http_version 1.1proxy_set_header Connection "",并在 upstream 里加 keepalive 16;


🟢缓存、压缩与限流

# 代理缓存(proxy_cache_path 只能在 http 上下文)
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:32m max_size=10g inactive=60m;

location /bbs/ {
    proxy_cache            mycache;
    proxy_cache_valid      200 1d;
    proxy_cache_valid      any 1m;
    proxy_cache_use_stale  error timeout http_500;
    add_header Nginx-Cache $upstream_cache_status;
    proxy_pass             http://172.16.100.11/;
}
# gzip
gzip on;
gzip_types text/css application/javascript application/json;
gzip_comp_level 6;
gzip_min_length 500;

# 静态资源缓存
location ~* \.(?:jpg|jpeg|gif|png|ico|woff2)$ {
    expires 1M;
    add_header Cache-Control "public";
    access_log off;
}

# 限流:每 IP 每分钟 30 次请求 / 最多 10 个并发连接
limit_req_zone  $binary_remote_addr zone=one:10m rate=30r/m;
limit_conn_zone $binary_remote_addr zone=addr:10m;

🟢TCP/UDP stream 代理

stream · least_conn · proxy_timeout · proxy_responses。Layer4 转发 MySQL、DNS 等非 HTTP 流量。

stream 位于 Layer4,效率高于 http 反向代理,编译需 --with-stream(官方镜像已自带)。

MySQL 负载均衡
stream {
    upstream mysql_servers {
        least_conn;
        server 120.120.120.120:3306 max_fails=3 fail_timeout=5s;
        server 120.120.120.121:3306 max_fails=3 fail_timeout=5s;
    }
    server {
        listen 9999;
        proxy_connect_timeout 5s;
        proxy_timeout 10s;
        proxy_next_upstream on;
        proxy_socket_keepalive on;
        proxy_pass mysql_servers;
    }
}
# UDP(DNS 负载均衡)
stream {
    upstream dns_upstreams {
        server 1.1.1.1:53 weight=1;
        server 8.8.8.8:53 weight=1 backup;
    }
    server {
        listen 53 udp;
        proxy_responses 1;     # UDP 专用:期望后端返回的包数
        proxy_timeout 20s;
        proxy_pass dns_upstreams;
    }
}

🟢安全

# 限速 / 限连接缓解 DDoS
limit_req  zone=one;
limit_conn addr 10;

# 关闭 Slowloris 式的慢连接
client_body_timeout 5s;
client_header_timeout 5s;

# IP 白名单
location / {
    allow 192.168.1.0/24;
    deny all;
}

# 按 UA 拦截
if ($http_user_agent ~* foo|bar) { return 403; }

🟢实战实例

proxy_pass · X-Forwarded-For · client_max_body_size。真实站点配置:Django、WebSocket、AI 工具、Seafile、OnlyOffice 与多站点入口。

flowchart LR
    C[/客户端/] --> N[Nginx :80 / :443]
    N -->|proxy_pass| App[应用 :8000]
    N -->|alias| S[静态文件目录]
    N -->|proxy_pass| OO[OnlyOffice / Seafile]

Django 反向代理

pbc.mibo.com
server {
    listen       80;
    server_name  pbc.mibo.com;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://10.44.3.3:12345/;
    }
    location /static/(?!grappelli) {
        alias /opt/mibo_pbc/static/;
    }
}

Django 侧

还需配置 CSRF_TRUSTED_ORIGINS

WebSocket / WSS

server {
    server_name a.hoao.mibo;
    listen 443 ssl;

    location / {
        proxy_pass http://127.0.0.1:10088;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

AI 工具(关闭缓存与缓冲)

server {
    listen 443 ssl;
    server_name c.hoao.fun;
    charset utf-8;
    autoindex on;
    proxy_cache off;                 # 关闭缓存
    proxy_buffering off;             # 关闭代理缓冲
    chunked_transfer_encoding on;    # 分块传输
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 300;

    location / {
        proxy_pass http://127.0.0.1:8523;
    }
}

Seafile

server {
    listen       80;
    server_name  doc.mibo.com;

    location / {
        proxy_pass http://10.44.3.12:37881/;
        client_max_body_size 0;
        proxy_set_header Forwarded "for=$remote_addr;proto=$scheme";
        proxy_set_header Host $http_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-Host $server_name;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout  36000s;
        proxy_read_timeout     36000s;
        proxy_send_timeout     36000s;
        send_timeout           36000s;
    }
}

OnlyOffice

server {
    listen       80;
    server_name  docwork.mibo.com;
    gzip on;
    location / {
        proxy_pass http://10.44.3.12:8022;
        proxy_set_header Forwarded "for=$remote_addr;proto=$scheme";
        proxy_set_header Host $http_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-Host $server_name;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout  36000s;
        proxy_read_timeout     36000s;
        proxy_send_timeout     36000s;
        send_timeout           36000s;
    }
}

子域重定向复用同一企微回调

把“登录域 + 子路径”转换为“子域 + 剩余路径”:

server {
    listen 80;
    server_name login.tech.intra.qq.com;
    location / {
        # http://login.tech.intra.qq.com/pbc/view_svn_log/4
        #   ==> http://pbc.tech.intra.qq.com/view_svn_log/4
        rewrite ^/([^/]+)/(.+)$ http://$1.tech.intra.qq.com/$2 last;
    }
}

rewrite 实现参数到路径的映射

/api/v1/game/data?id=<game_id>https://google.com/api/v1/new_game/<game_id>

location /api/v1/ {
    proxy_pass_header Server;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    proxy_http_version 1.1;
    if ($request_uri ~* "/api/v1/game/data\?id=(.*)") {
        set $id $1;
        rewrite .* /api/v1/new_game/$id break;
        proxy_pass http://gameid.escape.com;
    }
}

多站点入口(真实配置)

upstream font { server 127.0.0.1:12365; }
upstream aiai { server 10.66.244.44:8080; }

server {
    listen       80;
    server_name  mr_info.tech.intra.nsfocus.com;
    location / { proxy_pass http://10.66.244.152:5601/; }
}

server {
    listen 80;
    server_name  doc.tech.intra.nsfocus.com;
    location / {
        proxy_pass http://10.66.244.44:37881/;
        client_max_body_size 0;
        proxy_set_header Forwarded "for=$remote_addr;proto=$scheme";
        proxy_set_header Host $http_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-Host $server_name;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout  36000s;
        proxy_read_timeout     36000s;
        proxy_send_timeout     36000s;
        send_timeout           36000s;
    }
}

server {
    listen       80;
    server_name  pbc.tech.intra.nsfocus.com;
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:16610/;
    }
    location /static/(?!grappelli) { alias /opt/mibo_pbc/static/; }
}

server {
    listen       80;
    server_name  hal.tech.intra.nsfocus.com;
    location / {
        proxy_http_version 1.1;
        proxy_read_timeout 300;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        client_max_body_size 2500m;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:55330/;
    }
    location /static/(?!grappelli) { alias /opt/assetin/static; }
}

server {
    listen       80;
    server_name  nav.tech.intra.nsfocus.com;
    location / { proxy_pass http://127.0.0.1:3002/; }
}

server {
    listen       80;
    server_name  watch.tech.intra.nsfocus.com;
    location / { proxy_pass http://127.0.0.1:33001/; }
}

server {
    listen       80;
    server_name  ai.tech.intra.nsfocus.com;
    expires 1m;
    location /ui/chat/600b0cc9ed8e6aa8 {
        if ($remote_addr !~* "^10\.66\.30\.|^10\.66\.50\.") {
            return 301 /ui/chat/b5755153eb56bead;
        }
        proxy_pass http://aiai;
    }
    location / {
        if ($request_uri !~* "^/ui/chat/|api|css$|js$|svg$|woff2$|ttf$|woff$") {
            return 403;
        }
        proxy_pass http://aiai;
    }
}

# 默认站点跳转
server {
    listen 80 default_server;
    server_name _;
    return 301 http://nav.tech.intra.nsfocus.com;
}

# 静态字体目录直出
server {
    listen 12365 default_server;
    server_name _;
    location / {
        autoindex on;
        alias /opt/font/;
    }
}

🟢日常常用

# 不记录 favicon / robots
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt  { allow all; log_not_found off; access_log off; }
server {
    listen 80;
    location / { rewrite ^ https://$host$request_uri? permanent; }
}