首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么节点http客户端请求在大约5秒后偶尔出现“套接字挂断”错误?

为什么节点http客户端请求在大约5秒后偶尔出现“套接字挂断”错误?
EN

Stack Overflow用户
提问于 2022-07-21 22:49:33
回答 1查看 318关注 0票数 2

我有一个节点(v14.19.1)进程,它收集数据,然后通过向VictoriaMetrics发出http请求将其插入/api/v1/import。我使用axios发送请求。在绝大多数情况下,这是完美的。偶尔,客户端使用“套接字挂起”(带有以下堆栈)出错,数据永远无法到达数据库:

代码语言:javascript
运行
复制
Error: socket hang up
    at connResetException (internal/errors.js:639:14)
    at Socket.socketOnEnd (_http_client.js:499:23)
    at Socket.emit (events.js:412:35)
    at Socket.emit (domain.js:475:12)
    at endReadableNT (internal/streams/readable.js:1334:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)

有时,我看到了似乎与EPIPE一样明显的问题。当数据库和数据收集进程位于同一虚拟机上时,情况总是如此,但有时在不同的机器上也会发生这种情况:

代码语言:javascript
运行
复制
Error: write EPIPE
    at afterWriteDispatched (internal/stream_base_commons.js:156:25)
    at writeGeneric (internal/stream_base_commons.js:147:3)
    at Socket._writeGeneric (net.js:798:11)
    at Socket._write (net.js:810:8)
    at writeOrBuffer (internal/streams/writable.js:358:12)
    at Socket.Writable.write (internal/streams/writable.js:303:10)
    at ClientRequest._writeRaw (_http_outgoing.js:351:17)
    at ClientRequest._send (_http_outgoing.js:327:15)
    at ClientRequest.end (_http_outgoing.js:849:10)

日志记录显示,套接字挂起往往发生在请求启动后的5-6s左右,有时长达15s左右;这似乎不足以触发我所知道的任何连接超时。当发出更多/或更大的数据写入请求时,错误似乎更普遍,但有时也会在小写入时发生。

我越来越怀疑问题在于客户端(或它正在运行的虚拟机),而不是数据库。我的证据是:

  1. VictoriaMetrics没有记录与套接字挂起相对应的错误。
  2. 曾经有一台正在运行数据收集进程的dev机器填满了它的根硬盘驱动器,这造成了一系列问题,在此期间,该机器向数据库写入的每一次尝试都会导致套接字挂起(或EPIPE)。在这种情况下,不可能是数据库的错误,因为数据库位于不同的、未受影响的虚拟机上,而其他客户端则没有错误地将其写入其中。

特别是,第二点让我怀疑,我偶尔会碰到某些节点或OS (Ubuntu20.04),限制连接/文件/网络流量/等等,从而导致某些连接在较高流量期间被客户端(或其操作系统)过早关闭。我能做些什么来证实或反驳这种怀疑?或者还有什么其他的根本原因可以解释我所观察到的?

所有涉及的虚拟机都运行在Azure云中的专用网络(否则是可靠的)上。

EN

回答 1

Stack Overflow用户

发布于 2022-08-30 13:54:00

我似乎通过对我的客户端代码进行两次更改来解决这个问题:

  1. 正如@HeikoThei在注释中所建议的那样,我在axios配置中添加了以下内容,以限制每个进程的套接字数量。
代码语言:javascript
运行
复制
httpAgent: new http.Agent({maxSockets: 10}),
httpsAgent: new https.Agent({maxSockets: 10})
  1. 我使用axios-重试包重试由于网络错误而失败的任何写入请求。我使用了retryCondition: axiosRetry.isNetworkError;我必须显式地设置它,因为在默认情况下,只会保守地重试那些保证是幂等的请求,但是在这种情况下,我需要重试POST(我知道在这种情况下这样做是安全的)。

我不确定这些更改中的哪一个解决了问题,或者它们是否都起了作用,因为我同时实现了它们。但是,自从部署这些更改后,我还没有看到任何EPIPE或“套接字挂起”错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73073447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档