# ============================================================ # UAT 完整配置:uat.ailien.shop(443 + 80 跳转) # 仓库路径:alien_cloud/docs/nginx/conf.d/temp/ailien-uat.aliyun-ecs.conf # # 【部署说明】 # - 本文件在 conf.d/temp/ 下,不会被主配置 include conf.d/*.conf 自动加载。 # - 上线:复制或软链到 Nginx 宿主机,例如: # cp docs/nginx/conf.d/temp/ailien-uat.aliyun-ecs.conf /alien_prod/nginx/conf.d/ailien-uat.conf # - 依赖同目录上级:conf.d/00-common.conf(limit_req_zone payment_prepay、map $cors_origin) # - 片段:conf.d/temp/ailien-uat.inc.temp-tus-upload-verify-locations.conf(/files、/upload、/verify) # # 【路由分工】(与 upaibm_system Python 网关、Java alien-gateway 一致) # /ai/、/ai/ws → uat_ai_service(H100 upaibm gateway,UAT 端口 9300,勿用 30019) # /api/、/ → uat_gateway(alien-gateway,ECS 私网 IP + 宿主机映射端口) # /alienStore/ 等 → 可直连 store/second/dining,降低网关单点故障影响 # # 【upstream 核对】部署前在 Nginx 容器/宿主机执行 docker ps,对照宿主机 PORTS 修改下方 IP:端口。 # - 阿里云 ECS 私网示例:172.23.9.202(勿用公网 EIP 作 upstream,易 upstream timed out) # - AI 网关(upaibm):192.168.2.250:9300(见 upaibm_system gateway_service/.env.uat) # ============================================================ # 阿里云 ECS:Java 微服务与 alien-gateway(VPC 私网 IP) upstream uat_gateway { server 172.23.9.202:8001; # server 172.23.9.202:18000; # 若 compose 映射为 18000→容器 8000,改为此行并注释上一行 keepalive 32; } upstream uat_store { server 172.23.9.202:30014; # server 172.23.9.202:13004; # 部分 compose:13004→容器 30004 keepalive 8; } upstream uat_second { server 172.23.9.202:30015; # server 172.23.9.202:13005; # 部分 compose:13005→容器 30005 keepalive 8; } upstream uat_dining { server 172.23.9.202:30019; # server 39.106.135.88:30019; # dining 若在其它机器,改为实际 IP:端口 keepalive 8; } # 预生产 AI(upaibm_system gateway_service,Consul + /ai/{service}/...) upstream uat_ai_service { server 39.106.135.88:9300; # server 172.23.9.202:9300; # 若 AI 网关与 Java 同机且映射 9300,可改为此行 keepalive 32; } # 本机 upload 栈 nginx-gateway(docker-compose: 0.0.0.0:40007->80) upstream uat_upload_stack { server 127.0.0.1:40007; keepalive 8; } # 商户端 Tus/简单上传:同源 /ai-upload/ → 回环本 server 443(对齐 VITE_PROXY /ai-upload) upstream upl_ai_upload { server uat.ailien.shop:443; keepalive 8; } # --------------- UAT:https://uat.ailien.shop (443) --------------- server { listen 443 ssl; http2 on; server_name uat.ailien.shop; ssl_certificate /etc/nginx/ssl/ailien.shop.pem; ssl_certificate_key /etc/nginx/ssl/ailien.shop.key; ssl_session_timeout 1d; 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; access_log /var/log/nginx/uat/uat.ailien.shop.access.log main; error_log /var/log/nginx/uat/uat.ailien.shop.error.log warn; # 微信公众号 JS 接口安全域名校验(须在 location / 及网关代理之前) # 后台填写:uat.ailien.shop 磁盘:/cert/MP_verify_u6feCTxr5iTTBeIx.txt location = /MP_verify_u6feCTxr5iTTBeIx.txt { alias /cert/MP_verify_u6feCTxr5iTTBeIx.txt; default_type text/plain; add_header Content-Type "text/plain; charset=utf-8"; } # 商户端前端:https://uat.ailien.shop/group_web_merchant/ location /group_web_merchant/ { root /alien_uat/nginx/html; index index.html; try_files $uri $uri/ @uat_merchant_spa; } location @uat_merchant_spa { root /alien_uat/nginx/html; try_files /group_web_merchant/index.html =404; } location = /group_web_merchant { return 301 $scheme://$host/group_web_merchant/; } # GroupWeb:https://uat.ailien.shop/group_web/ 中台 location /group_web/ { root /alien_uat/nginx/html; index index.html; try_files $uri $uri/ @uat_group_spa; } location @uat_group_spa { root /alien_uat/nginx/html; try_files /group_web/index.html =404; } location = /group_web { return 301 $scheme://$host/group_web/; } # GroupLawyerWeb:https://uat.ailien.shop/group_lawyer_web/ location /group_lawyer_web/ { root /alien_uat/nginx/html; index index.html; try_files $uri $uri/ @uat_lawyer_spa; } location @uat_lawyer_spa { root /alien_uat/nginx/html; try_files /group_lawyer_web/index.html =404; } location = /group_lawyer_web { return 301 $scheme://$host/group_lawyer_web/; } # HBuilder 分享页等:勿走网关,否则 Spring Whitelabel 404。须写在 location / 之前。 location ^~ /h5/HBuilderProjects/ { root /alien_uat/nginx/html; try_files $uri =404; add_header Cache-Control "public, max-age=300"; } # AI WebSocket(wss://uat.ailien.shop/ai/ws/... → upaibm gateway) location /ai/ws { proxy_pass http://uat_ai_service; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; 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 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; } # AI HTTP(/ai/life-manager/... 等,upaibm Python 微服务) location /ai/ { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $cors_origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS'; add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Max-Age' 3600; add_header 'Content-Length' 0; return 204; } add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always; proxy_pass http://uat_ai_service; 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_connect_timeout 60s; proxy_send_timeout 300s; proxy_read_timeout 300s; } # WebSocket 直连 alien-store:/alienStore/socket/xxx → /socket/xxx location /alienStore/socket/ { rewrite ^/alienStore/socket/(.*)$ /socket/$1 break; proxy_pass http://uat_store; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; 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 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; } # HTTP 直连 alien-store(网关故障时 App 仍可访问 store API) location /alienStore/ { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $cors_origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS'; add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Max-Age' 3600; add_header 'Content-Length' 0; return 204; } proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Credentials; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Allow-Headers; proxy_hide_header Access-Control-Expose-Headers; proxy_hide_header Access-Control-Max-Age; add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Vary Origin always; proxy_pass http://uat_store; 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 $connection_upgrade; proxy_connect_timeout 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; } # HTTP 直连 alien-second location /alienSecond/ { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $cors_origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS'; add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Max-Age' 3600; add_header 'Content-Length' 0; return 204; } proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Credentials; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Allow-Headers; proxy_hide_header Access-Control-Expose-Headers; proxy_hide_header Access-Control-Max-Age; add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Vary Origin always; proxy_pass http://uat_second; 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 $connection_upgrade; proxy_connect_timeout 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; } # 点餐 SSE 长连接:直连 alien-dining location /alienDining/store/order/sse/ { rewrite ^/alienDining/(.*)$ /$1 break; proxy_pass http://uat_dining; 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_connect_timeout 60s; proxy_send_timeout 86400s; proxy_read_timeout 86400s; proxy_buffering off; } # 支付预下单限流(依赖 00-common.conf 中 limit_req_zone payment_prepay) location ~* payment/prePay { limit_req zone=payment_prepay burst=1 nodelay; limit_req_status 429; add_header X-Payment-Limit "applied" always; rewrite ^/api/(.*)$ /$1 break; proxy_pass http://uat_gateway; 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 $connection_upgrade; proxy_connect_timeout 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $cors_origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS'; add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Max-Age' 3600; add_header 'Content-Length' 0; return 204; } proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Credentials; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Allow-Headers; proxy_hide_header Access-Control-Expose-Headers; proxy_hide_header Access-Control-Max-Age; add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Vary Origin always; } # /api/xxx → 去前缀后转发 Java alien-gateway location /api/ { rewrite ^/api/(.*)$ /$1 break; proxy_pass http://uat_gateway; 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 $connection_upgrade; proxy_connect_timeout 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $cors_origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS'; add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Max-Age' 3600; add_header 'Content-Length' 0; return 204; } proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Credentials; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Allow-Headers; proxy_hide_header Access-Control-Expose-Headers; proxy_hide_header Access-Control-Max-Age; add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Vary Origin always; } # 静态上传目录(宿主机 /uploads) location ^~ /uploads/ { alias /uploads/; try_files $uri =404; add_header Cache-Control "public, max-age=86400"; } # 商户端同源上传代理:/ai-upload/ → https://uat.ailien.shop(去掉 /ai-upload 前缀) location = /ai-upload { return 301 $scheme://$host/ai-upload/; } location ^~ /ai-upload/ { rewrite ^/ai-upload(.*)$ $1 break; proxy_pass https://upl_ai_upload; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_ssl_server_name on; proxy_ssl_name uat.ailien.shop; proxy_set_header Host uat.ailien.shop; 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 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; client_max_body_size 0; proxy_request_buffering off; } # Tus /upload /verify(片段与 conf.d/temp/ailien-uat.inc.temp-tus-upload-verify-locations.conf 同步) include conf.d/temp/ailien-uat.inc.temp-tus-upload-verify-locations.conf; # 其余请求 → Java alien-gateway location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $cors_origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS'; add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Max-Age' 3600; add_header 'Content-Length' 0; return 204; } proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Credentials; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Allow-Headers; proxy_hide_header Access-Control-Expose-Headers; proxy_hide_header Access-Control-Max-Age; add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Vary Origin always; proxy_pass http://uat_gateway; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; 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 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; } } # --------------- UAT:HTTP 80 → HTTPS 443(微信域名校验文件须 HTTP 可访问) --------------- server { listen 80; server_name uat.ailien.shop; access_log /var/log/nginx/uat/uat.ailien.shop.80.access.log main; error_log /var/log/nginx/uat/uat.ailien.shop.80.error.log warn; location = /MP_verify_u6feCTxr5iTTBeIx.txt { alias /cert/MP_verify_u6feCTxr5iTTBeIx.txt; default_type text/plain; add_header Content-Type "text/plain; charset=utf-8"; } location / { return 301 https://$host$request_uri; } }