Nginx部分浏览器API调用出现500错误,寻求技术建议
部分浏览器/设备调用API返回500错误的排查思路与建议
问题现象
- 部分浏览器/设备调用服务器API接口时返回500错误,页面提示:
The page you are looking for is temporarily unavailable.
Please try again later.
- 存在浏览器间差异:本地Firefox报错,Chrome正常;也有客户反馈Chrome浏览器出现该错误。
服务器日志信息
Nginx访问日志(路径/nginx/localhost)记录示例:
94.xxx.xxx.xxx:- - - [05/Oct/2022:11:10:33 +0000] "POST /api/auth/login HTTP/3" 500 383 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:104.0) Gecko/20100101 Firefox/104.0" "-" "www.mydomain.com"
环境与Nginx配置
服务器部署在Jelastic平台,作为负载均衡器转发流量至后端服务器,Nginx配置如下:
######## HTTP SECTION PROTOTYPE ######## http { server_tokens off ; include /etc/nginx/mime.types; default_type application/octet-stream; set_real_ip_from 192.xxx.xxx.xxx/16; set_real_ip_from 10.xxx.xxx.xxx/8; set_real_ip_from 172.xxx.xxx.xxx/16; real_ip_header X-Forwarded-For; real_ip_recursive on; log_format main '$remote_addr:$http_x_remote_port - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$host" sn="$server_name" ' 'rt=$request_time ' 'ua="$upstream_addr" us="$upstream_status" ' 'ut="$upstream_response_time" ul="$upstream_response_length" ' 'cs=$upstream_cache_status' ; client_header_timeout 10m; client_body_timeout 10m; send_timeout 10m; client_max_body_size 100m; proxy_read_timeout 300s; connection_pool_size 256; client_header_buffer_size 1k; large_client_header_buffers 4 32k; # 8k to 32k request_pool_size 4k; #Allow large token proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; #proxy_buffering off; # gzip on; gzip_min_length 1100; gzip_buffers 4 8k; gzip_types text/plain; output_buffers 1 32k; postpone_output 1460; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 75 20; ignore_invalid_headers on; ### UPSTREAMS LIST FOLLOWS HERE ### #upstream nodes{ server XXX.XXX.XXX.XXX; server 127.0.0.1:8001 backup # UPSTREAMPROTO # This is upstream prototype line, do not remove this! } #This config is auto-generated. DO NOT modify the weight property. If changing the rest of settings, please, remember that you are doing this at your own risk. upstream common { check interval=30000 rise=2 fall=5 timeout=10000 default_down=false type=http; check_http_send "GET / HTTP/1.1 Host: localhost "; keepalive 100; server mydomain.jcloud-ver-jpe.ik-server.com weight=100 ; } ### UPSTREAMPROTO for common ### #GFADMIN server { listen *:80; listen [::]:80; server_name _; access_log /var/log/nginx/localhost.access_log main; error_log /var/log/nginx/localhost.error_log info; proxy_temp_path /var/nginx/tmp/; proxy_connect_timeout 5s; error_page 500 502 503 504 /50x.html; proxy_next_upstream error timeout http_500; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Host $http_host; proxy_set_header X-Forwarded-For $http_x_forwarded_for; proxy_set_header X-Remote-Port $http_x_remote_port; proxy_set_header X-URI $request_uri; proxy_set_header X-ARGS $args; proxy_set_header Refer $http_refer; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; if ($http_x_remote_port = '' ) { set $http_x_remote_port $remote_port; } location = /50x.html { root html; } location / { proxy_pass http://common; } #USERLOCATIONS } # server { # listen *:8001; # server_name backup.local; # # location / { # proxy_pass http://default_upstream; # add_header Set-Cookie "SRVGROUP=$group; path=/; HttpOnly"; # proxy_http_version 1.1; # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; # proxy_set_header X-Host $http_host; # proxy_set_header X-Forwarded-For $http_x_forwarded_for; # proxy_set_header X-URI $request_uri; # proxy_set_header X-ARGS $args; # proxy_set_header Refer $http_refer; # proxy_set_header Upgrade $http_upgrade; # proxy_set_header Connection "upgrade"; # } # } include /etc/nginx/conf.d/*.conf; } ######## TCP SECTION PROTOTYPE ########
排查思路与建议
1. 检查后端服务器应用日志
- 查看后端服务器(
mydomain.jcloud-ver-jpe.ik-server.com)的应用日志,确认是否针对特定请求(比如HTTP/3、特定UA的请求)抛出异常,导致返回500。 - 重点关注Nginx日志中的
us="$upstream_status"字段,判断500是后端返回还是Nginx自身产生的。
2. 分析HTTP协议版本差异
日志中报错的请求使用HTTP/3,需确认:
- 后端服务器是否支持HTTP/3?若后端不支持,Nginx转发HTTP/3请求时可能出现异常。
- 当前Nginx配置无明确的HTTP/3(QUIC)监听规则,若客户端发起HTTP/3请求,Nginx可能无法正确处理。
3. 排查请求头差异
不同浏览器的请求头存在差异,可能触发异常:
- 收集报错浏览器和正常浏览器的完整请求头,对比
Upgrade、Connection、User-Agent等字段的差异。 - 当前Nginx强制设置
Connection "upgrade",对于普通POST登录请求可能不合适,可针对/api/auth/login路径单独取消该设置:location /api/auth/login { proxy_pass http://common; proxy_set_header Connection ""; }
4. 提升Nginx日志级别
将error_log级别从info改为debug,获取更详细的错误信息:
error_log /var/log/nginx/localhost.error_log debug;
5. 验证上游健康检查
当前上游配置了健康检查,需确认健康检查请求(GET / HTTP/1.1 Host: localhost)是否能正常获取响应,确保后端服务器处于健康状态。若健康检查失效,Nginx可能转发请求到异常节点。
6. 直接测试后端接口
绕过Nginx,直接访问后端服务器的/api/auth/login接口,模拟报错浏览器的请求参数和头信息,确认是否能正常返回,定位问题出在Nginx还是后端应用。
内容的提问来源于stack exchange,提问作者Bogy
相关产品推荐
相关产品推荐

