当nginx反向代理遇到502错误

  • 最近我司某业务(nginx 1.22.0反向代理后端Java服务,不涉及php)在运行一段时间后不定期出现502 Bad Gateway,nginx日志报错如下:
2023/10/16 15:10:26 [error] 54381#0: *15225751 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: x.x.x.x, server: _, request: "GET /manager HTTP/1.0, upstream: "http://x.x.x.x:300081/manager", host: "x.x.x.x"
  • 该业务在公网与内网环境的访问逻辑如下,其中内网用户访问一直ok,而公网则不定期出现502错误,所以排除路由器及k8s容器,初步判定问题出在公网nginx服务器上
方式1:公网用户 --> nginx(公网域名:port) --> 路由器映射端口(内网ip:port) --> k8s(nginx代理java服务)
方式2:内网用户 --> 路由器映射端口(内网ip:port) --> k8s(nginx代理java服务)

分析过程

  • 由于nginx这一类的代理出现Connection reset的场景复杂,原因多样,最常见的原因是上传文件过大,传输时间过长,然后连接被中断
  • 本案例中公网nginx使用的是HTTP 1.0,而后端k8s容器中nginx使用的是HTTP 1.1(注:HTTP 1.1协议默认开启keepalive功能),所以猜测可能是前端nginx与后端java服务或后端nginx的keepalive timeout时间不一致导致此问题的发生

注:执行 curl -I http://ip地址 可以参看HTTP协议版本

处理步骤

  • 第1步,调整nginx.conf如下参数,启用 http 1.1 协议以支持长连接,并根据实际情况调整timeout参数
worker_processes auto;                  #.核心参数
worker_rlimit_nofile 65535;
#.其他省略...

events {
    use epoll;
    worker_connections 30000;           #.核心参数,请根据实际情况调整
    multi_accept on;
}

http {
    #.其他省略...
    keepalive_timeout 120;              #.核心参数,请根据实际情况调整
    keepalive_requests 1000;            #.核心参数,请根据实际情况调整
    client_header_timeout 10;           #.核心参数,请根据实际情况调整
    client_body_timeout 10;             #.核心参数,请根据实际情况调整
    send_timeout 600;                   #.核心参数,请根据实际情况调整

    server {
        listen 80;
        location / {
            #.其他省略...
            proxy_pass http://xxx:30081;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Connection keep-alive;     #.核心参数,指定Connection为keep-alive
            proxy_http_version 1.1;                     #.核心参数,启用http1.1协议
            proxy_connect_timeout 300s;                 #.核心参数,请根据实际情况调整
            proxy_send_timeout 300s;                    #.核心参数,请根据实际情况调整
            proxy_read_timeout 300s;                    #.核心参数,请根据实际情况调整
            client_max_body_size 50m;                   #.核心参数,请根据实际情况调整
        }
    }
}
  • 第2步,先执行 nginx -t 确认参数无误,再执行 nginx -s reload 热重启nginx服务
  • 第3步,设置 ulimit 系统最大打开的文件数量
ulimit -SHn 65535
cat /etc/rc.local | grep ulimit || echo "ulimit -HSn 65535" >> /etc/rc.local
  • 第4步,优化linux内核,修改 /etc/sysctl.conf 配置如下参数,然后 /sbin/sysctl -p /etc/sysctl.conf 使配置立即生效
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1                   #.核心参数
net.ipv4.tcp_tw_recycle = 1                 #.核心参数
net.ipv4.tcp_timestamps = 1                 #.核心参数
net.ipv4.tcp_keepalive_time = 300           #.核心参数,请根据实际情况调整
net.ipv4.tcp_max_tw_buckets = 10000         #.核心参数,请根据实际情况调整
net.ipv4.ip_local_port_range = 1024 65535
net.core.somaxconn = 8192                   #.核心参数,请根据实际情况调整

以上,第1、2步必做,第3、4步选做

Copyright © www.sqlfans.cn 2023 All Right Reserved更新时间: 2023-10-24 10:23:14

results matching ""

    No results matching ""