请教一个 socket hang up 的报错问题【已解决】
发布于 8 个月前 作者 ZhangDianPeng 1559 次浏览 最后一次编辑是 7 个月前 来自 问答

请教一个问题,在使用 http.request的 时候偶现 socket hang up,报错如下: at createHangUpError (_http_client.js:329:15) 而且只有在用使用agent的时候会出现, agent配置如下: opts = { maxSockets: 100, maxFreeSockets: 10, timeout: 10 * 60 * 1000, keepAliveTimeout: 30000 }

Node版本8.7.0 agentkeepalive版本 2.2.0

另外使用官方的agent也会出现这个问题

10 回复

如果连接成功之前调用 req.abort(),则依次触发以下事件: … ‘error’ 事件并带上错误信息 ‘Error: socket hang up’ 和错误码 ‘ECONNRESET’。

socket hang up是建立连接失败, 看下是不是服务器不支持keep-alive

@dewfall123 通过抓包找到原因了,是因为公司运维nginx配置问题

nginx 配置的 keepalive_timeout 只有 5s

而 agentkeepalive 中的 freeKeepAliveTimeout 配置是 30 s

所以在长连接的情况下,如果 socket 处于空闲状态的超过 5s,那么 nginx 侧会主动强制断掉 socket 连接,这时恰好客户端如果又在这个连接上发了一个请求,触发 socket hang up 报错信息,所以在并发量比较大的情况下,偶尔会触发这个报错。

所以建议如果配置长连接的情况下,服务端的 freeKeepAliveTimeout 时间一定要比客户端的长,才不会出现该问题。

如果是用 Node 启动作为服务端的话,可以通过 server.keepAliveTimeout 设置超时时间。

官方的这个 默认值 是 5s, 感觉是一个坑,时间太短,如果对应的客户端使用长连接的话,建议将其调大。

@ZhangDianPeng nginx关闭socket时应该会通知客户端吧。 node应该收到信息后将socket释放掉。 所以你们只有在并发量很大的时候才能遇到是吧?

@Gitforxuyang nginx在通知客户端的后,客户端还没有接收到,这个时候客户端会再次发请求,但是nginx已经强制关掉了socket,导致当前这个请求挂掉

默认的keepAliveTimeout是1s吧,默认的一般都够了,30s的心跳包有点太大了

@royalrover 看官方文档是5秒

http.agent的配置项只有timeout和keepAliveMsecs吧,你的配置keepAliveTimeout不太对。

@ZhangDianPeng 只要保证后端业务服务器的keepalive超时和nginx的超时一致即可,没法估计客户端什么时候会开启下一个。请求另外,你们的nginx与后端服务器采用的是长连接吗?如果采用默认的短连接,性能更差

@royalrover 这里的客户端和服务端都是两个node微服务,中间搭了一层nginx

@royalrover 2.2.0版本是keepAliveTimeout agentkeepalive2.x

回到顶部