nginx 代理 nexus 私服仓库出现 502

1、背景

nginx 作为 nexus 的反向代理,maven 配置的 nexus 地址指向的是 nginx

2、问题

mvn 编译构建时候出现个别的包或 pom 文件下载返回 502 导致编译失败,在同一个 VPC 内的 mvn 客户端不会出现该问题,跨云账号通过云企业网组网访问的 mvn客户端会出现 502,10 次构建有 8-9 次出现,复现率很高,如果跳过 nginx直接访问 nexus就没问题

3、排查过程

nginx日志如下

{"method":"GET","uri":"/nexus/content/groups/lkb-public/org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.pom.sha1",
"status":"502",
"X-Forwarded-For":"-",
"response_time":"7.012",
"request_time":"7.009",
"upstream_connect_time":"-",
"upstream_header_time":"-",
"userAgent":"Apache-Maven/3.6.3 (Java 1.8.0_333; Linux 5.15.0-142-generic)","request_length":"370","bodySize":"150","authorization":"-","x-auth-token":"-","EagleEye-TraceID":"-"}

nexus 查看 TCP 连接

    netstat -anptu

    有 500 多个连接,其中 200 多个 CLOSE_WAITE,其余是ESTABLISHED

 

4、故障分析

由于 nginx之前未开启长连接,默认都是短连接,mvn下载的每一个文件都会创建一个新的 TCP 连接,多个下载不会复用同一个连接,mvn编译过程有几百个 pom jar下载就会导致有几百个 TCP 连接建立,这个数值对于 linux系统而已未达瓶颈,但是对 nexus而言已经到了它连接池的上线了,满了之后新的请求过来只在等待队列里面,不会处理请求,nginx会对于这种建立 TCP 连接后无响应的连接在过了几秒钟后判断为连接不可用或异常遂返回 502

5、解决

nginx增加如下配置参数

 

upstream repo{

    server 1.1.1.1:8081; # 新增:长连接复用配置(解决偶发连接中断)

    keepalive 32; # 保持 32 个空闲长连接

    keepalive_timeout 60s; # 空闲连接超时(与 Nexus 适配)

    keepalive_requests 100; # 单个长连接最大处理请求数 }
...

location / {
  proxy_pass http://repo;
  # 新增:启用 HTTP/1.1 长连接(核心修复偶 502)
  proxy_http_version 1.1;
  proxy_set_header Connection ""; # 清空 Connection 头,启用 keepalive
}

...

相关配置解释

  proxy_http_version 1.1;  proxy_set_header Connection ""; 为了开启长连接,可以理解为开关,但是仅仅如此还不够,只是每次连接后 TCP 不会关闭,不会让多个请求复用同一个 TCP 连接

keepalive 32; 是关键,永远有 32 空闲 TCP 长连接存在,请求进来都复用这 32个,如果单个最大处理 100 个(keepalive_requests 100;)打满后可以在 32 基础上新增连接,没有上限。如果没有请求了,也不会释放所以连接会保留 32 个,避免频繁新建 TCP,较少三次握手等开销

 

6、相关扩展

502 与 504 区别

502 和 504 是 Nginx 反向代理场景下最常见的两个错误码,核心区别在于 错误触发的阶段和原因:
  • 502 = 上游服务器「连接失败 / 处理异常」(网关能连但上游 “坏了”);
  • 504 = 上游服务器「连接成功但响应超时」(网关连得上但上游 “太慢 / 没回应”)。
结合你的 Nexus 代理场景(跨 VPC、长连接 / 短连接、超时配置),用「通俗类比 + 技术拆解 + 场景对应」的方式,把两者的区别讲透:

 核心区别总表(一目了然)

image

 

TCP 中的 CLOSE_WAIT 、TIME_WAIT 存在场景

TCP 连接的建立(三次握手)和关闭(四次挥手)过程中,客户端与服务端会经历一系列明确的状态变迁。这张图能清晰展示完整流程与对应状态:

TCP 三次握手(建立连接)

  1. 客户端:从 CLOSED 发起连接,发送 SYN 包后进入 SYN_SENT 状态,等待服务器确认。

  2. 服务端:在 LISTEN 状态下收到 SYN 包,回复 SYN+ACK 包后进入 SYN_RCVD 状态。

  3. 客户端:收到 SYN+ACK 后,发送 ACK 包并立即进入 ESTABLISHED 状态。
  4. 服务端:收到最终的 ACK 包后,也进入 ESTABLISHED 状态,双方开始传输数据。

TCP 四次挥手(关闭连接)

  1. 主动关闭方(如客户端):发送 FIN 包,进入 FIN_WAIT_1 状态,等待对方的 ACK

  2. 被动关闭方(如服务端):收到 FIN 包后发送 ACK 确认,进入 CLOSE_WAIT 状态(此时仍可发送剩余数据)。

  3. 主动关闭方:收到 ACK 后进入 FIN_WAIT_2 状态,等待对方的 FIN 包。
  4. 被动关闭方:完成数据发送后,发送自己的 FIN 包,进入 LAST_ACK 状态,等待最后的 ACK
  5. 主动关闭方:收到 FIN 包后发送 ACK 确认,并进入 TIME_WAIT 状态(等待 2MSL 时间,确保对方收到 ACK)。
  6. 被动关闭方:收到最终的 ACK 后,立即进入 CLOSED 状态。
  7. 主动关闭方:TIME_WAIT 超时后,进入 CLOSED 状态,连接彻底关闭。

核心状态速查表

image

 

根据上述分析,time_wait属于正常情况,如果有大量短链接的话由于有释放时长(2MSL)短期内会有大量的此种状态

close_wait如果大量存在属于异常状况,说明被动关闭接收方没有进行后续的回包

 





  

posted @ 2025-12-12 11:59  fanggege  阅读(1)  评论(0)    收藏  举报