64 lines
2.3 KiB
Plaintext
64 lines
2.3 KiB
Plaintext
# 网关示例:静态前端 + /api 反向代理 + /ai/stream SSE 流式代理 + 限流 + 按 Cookie 灰度
|
|
# 运行 test_gateway.py 时会把 {{...}} 占位符替换成临时端口和目录
|
|
worker_processes 1;
|
|
error_log {{PREFIX}}/error.log warn;
|
|
pid {{PREFIX}}/nginx.pid;
|
|
events { worker_connections 256; }
|
|
|
|
http {
|
|
access_log off;
|
|
# 非 root 运行时,把临时文件目录放到可写位置
|
|
client_body_temp_path {{PREFIX}}/client_body;
|
|
proxy_temp_path {{PREFIX}}/proxy;
|
|
fastcgi_temp_path {{PREFIX}}/fastcgi;
|
|
uwsgi_temp_path {{PREFIX}}/uwsgi;
|
|
scgi_temp_path {{PREFIX}}/scgi;
|
|
|
|
# 每个 IP 每秒 5 个请求,突发最多 5 个
|
|
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
|
|
limit_req_status 429;
|
|
|
|
upstream api_stable { server 127.0.0.1:{{STABLE_PORT}}; keepalive 16; }
|
|
upstream api_canary { server 127.0.0.1:{{CANARY_PORT}}; keepalive 16; }
|
|
|
|
# Cookie canary=1 的用户走新版本,其余走稳定版本
|
|
map $cookie_canary $api_backend {
|
|
default api_stable;
|
|
"1" api_canary;
|
|
}
|
|
|
|
server {
|
|
listen 127.0.0.1:{{LISTEN_PORT}};
|
|
|
|
# 前端单页应用:找不到文件时回退到 index.html,交给前端路由
|
|
location / {
|
|
root {{PREFIX}}/html;
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
location /api/ {
|
|
limit_req zone=api_limit burst=5 nodelay;
|
|
proxy_pass http://$api_backend;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Connection "";
|
|
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 3s;
|
|
proxy_read_timeout 30s;
|
|
}
|
|
|
|
# 大模型流式输出(SSE):关闭缓冲,否则 Nginx 攒满缓冲区才发给浏览器
|
|
location /ai/stream {
|
|
proxy_pass http://api_stable;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Connection "";
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
proxy_read_timeout 300s; # 生成时间长,读超时要放宽
|
|
add_header X-Accel-Buffering no;
|
|
}
|
|
}
|
|
}
|