Products
GG网络技术分享 2025-03-18 16:13 1
问题描述:
近期平台对外开放了数据查询接口,在数据量特别大时,返回结果时间可能会超过3秒,接口开放后,系统本身调用没有问题,其他第三方平台接入时,总会报链接超时问题;
问题原因:
查看tomcat日志无任何错误,一开始以为是tomcat接收参数最大限制问题,对tomcat做了一次整体优化,修改连接数、修改post限制,问题仍存在;那问题可能出在nginx转发上面;
经排查,而在nginx中出现了499的错误,官方解释是nginx定义的一个状态码,用于表示这样的错误:
错误原因
1、nignx做proxy时,频繁的post,nginx认为不安全,记录499
可以在nignx的proxy配置中开启 proxy_ignore_client_abort on 功能是:确定在客户端关闭连接时是否应该关闭与代理服务器的连接,而不再等待响应
如果使用了proxy_ignore_client_abort on。 那么客户端主动断掉连接之后,Nginx 会等待后端服务器处理完(或者超时),然后记录“后端的返回信息”到日志。因此,如果后端返回200,就记录200 ;如果后端返回5XX ,那么就记录 5XX。
如果超时(默认60s,可以用 proxy_read_timeout 和proxy_send_timeout设置),Nginx 会主动断开连接,记录504
2、服务器返回http头之前,客户端就提前关闭了http连接,客户端请求服务端时,服务端响应慢,客户端觉得时间长主动关闭了连接, 比如浏览器(客户端)请求一个接口觉得很慢,就关掉了浏览器、 nginx做proxy的时候,后端执行时间长(如执行sql慢,调用其它接口慢)等,应该从后端去优化下,
通用解决方案:
1.499网上的解释是客户端主动关闭了连接
在一个项目上传文件的时候,nginx log报499,关闭iptables就可以
2.从排除故障的方法来说
nginx->tomcat,问题就出在这两个上面
看nginx的请求是否在日志里面能发现,这次是post请求是499
看tomcat的日志,是否有异常
3.从网络层,应用层,从下至上排除
iptables和网络方面的问题
4.使用工具
tcpdump
tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854 -w /tmp/post.log
tcpdump -i eth0 '((port 8000) and (tcp[(tcp[12]>>2):4]=0x47455420))' -nnAl -w /tmp/GET.log
0x4745 是post请求
5、设置客户端连接超时时间
发现第三方的请求是用的httpclient代理模式,而httpclient的链接超时时间设置的是2秒,在服务端还未返回数据是,就关闭了链接,调大httpclient的链接超时时间即可;
最近项目中用到了nginx,后台用的是Java, 发现有一个请求后台处理操过了1分钟,结果请求Status Code为504 Gateway Time-out.
理解了下nginx 所有timeout相关的配置,如下:
HTTP 有一个 KeepAlive 模式,它告诉 webserver 在处理完一个请求后保持这个 TCP 连接的打开状态。若接收到来自客户端的其它请求,服务端会利用这个未被关闭的连接,而不需要再建立一个连接。
http keep-alive, 網頁的每一個請求都是HTTP (圖片, CSS等), 而打開HTTP 請求是要先建立TCP 連接, 而如果一個頁面每個請求都要打開及關閉一個TCP 連接就會做成資源的浪費. keepalive_timeout 就是當一個HTTP 請求完成, 其TCP 連接會存留下來的時間, 如果這時有另一個HTTP 請求過來, 會複用這個TCP 連接, 如果再沒有新的請求過來, 才會關閉其TCP連接
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } 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; client_max_body_size 8192m; #gzip on; #include /etc/nginx/conf.d/*.conf; server { listen 80 so_keepalive=30m::; listen 443 default ssl; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/portalkey.key; #ssl_password_file /etc/nginx/ssl/ssl.pass; ssl_session_timeout 5m; ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { proxy_request_buffering off; proxy_pass http://127.0.0.1:8011/; proxy_connect_timeout 180; proxy_send_timeout 180; proxy_read_timeout 180; send_timeout 180; } location /test1_url/ { proxy_pass http://127.0.0.1:8008/; proxy_connect_timeout 180; proxy_send_timeout 180; proxy_read_timeout 180; send_timeout 180; } location /test2_url/ { proxy_pass http://127.0.0.1:3000/; proxy_connect_timeout 180; proxy_send_timeout 180; proxy_read_timeout 180; send_timeout 180; } } } |
# 配置段: http,默认75s
keepalive_timeout 60;
send_timeout:发送数据至客户端超时, 默认60s, 如果连续的60s内客户端没有收到1个字节, 连接关闭
proxy_connect_timeout: nginx与upstream server的连接超时时间
proxy_read_timeout: nginx接收upstream server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭
proxy_send_timeout: nginx发送数据至upstream server超时, 默认60s, 如果连续的60s内没有发送1个字节, 连接关闭
so_timeout:
當用戶跟SERVER開啟了TCP CONNECTION --> 一段長時間這個CONNECTION 沒traffic (so_keepalive timeout) --> SERVER 發出探測包看用戶是否還存在 --> 若探測包沒回, 則關閉TCP CONNECTION
so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt] |
so_keepalive=30m::10 will set the idle timeout (TCP_KEEPIDLE) to 30 minutes, leave the probe interval (TCP_KEEPINTVL) at its system default, and set the probes count (TCP_KEEPCNT) to 10 probes. |
以上三个参数只能使用一个,不能同时使用, 比如so_keepalive=on, so_keepalive=off或者so_keepalive=30s::(表示等待30s没有数据报文发送探测报文)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多关注本网站。
Demand feedback