Node.js-Fastify:连接在睡眠期间关闭setTimeout

问题描述

使用Fastify的Node.js服务器出现问题。

在执行请求的某个时刻,服务器似乎正在关闭连接,而客户端却收到套接字挂起错误

服务器中的逻辑是:

  • 增强客户端调用服务的能力。
  • 使用Axios发送HTTP请求以获取某些信息的服务。该服务实现了一种重试机制,并且每次重试后都会等待15秒以确保信息可用。

代码如下:

强化服务器:

from django.db.models import Count

labels = []
data = []

queryClientCompany = company.objects.annotate(
    c=Count('clients__cid')
)

for comp in queryClientCompany:
    labels.append(comp.name)
    data.append(comp.c)

服务:

fastify.post('/request',async (request,reply) => {
  try {
    const result = await service.performOperation(request.body);
    return result;
  } catch(error) {
    console.error('Error during operation: %s',error.toString());
    throw error;
  }
})

fastify.addHook('onError',(request,reply,error,done) => {
  console.error('onError hook: %o',error);
  done();
})

问题在于服务器似乎正在关闭连接。

根据日志,这是在等待15秒钟之后,在通过Axios进行呼叫之前,在完成第一次尝试之前发生的。

您可以在日志中看到,在关闭连接后,逻辑将继续进行并完成所有尝试,而不会出现任何问题。

日志中没有任何内容说明为什么关闭连接,甚至从声明的Fastify onError钩子也没有。

Axios也没有。我猜是否有超时会引发异常并被记录。

重要提示

请注意,如果我更改waitBeforeAttempt实现以实现忙等待而不是setTimeout,则连接不会被丢弃,即:

async function performOperation(request) {
  let attempt = 0;
  let latestErrorMessage;
  while(attempt++ < 5) {
    try {
      await waitBeforeAttempt();
      return await getInfoFromServer(request);
    } catch (error) {
      latestErrorMessage = getErrorMessage(error);
      if (attempt < 5) {
        console.log(`Re-attempting after error: ${latestErrorMessage}`);
      }
    }
  }
  throw new Error(`Error after 5 attempts. Last error: ${latestErrorMessage}`);
}

function waitBeforeAttempt() {
  return new Promise(resolve => setTimeout(resolve,15000));
}

async function getInfoFromServer(request) {
  const response = await axios.post('http://localhost:3000/service',request,{timeout: 120000});
  return response.data.toString();
}

我做错了什么导致连接断开吗?也许15秒的等待时间太长了?通过Puppetter(与我的实现方式相同),代码中还有其他setTimeout似乎没有引起问题。

解决方法

回答我自己的问题。原来,问题与等待或超时无关。

Node.js服务在本地运行时不会发生这种情况,只有在Kubernets + Nginx上运行时才会间歇性地发生。

Nginx只是重新启动而没有任何明显的原因。

Nginx已更新,问题不再显示。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...