Node.js - Fastify:连接在睡眠期间关闭(setTimeout)
Node.js - Fastify: Connection closed during sleep (setTimeout)
我在使用 Fastify 的 Node.js 服务器上遇到问题。
在请求执行期间的某个时刻,服务器似乎正在关闭连接并且客户端收到套接字挂起错误。
服务器中的逻辑是:
- Fastify 客户端调用服务。
- 服务使用 Axios 发送 HTTP 请求以获取某些信息。该服务实现了重试机制,每次重试后,它会等待 15 秒以确保信息可用。
代码如下:
Fastify 服务器:
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();
})
服务:
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 秒之后,在通过 Axios 调用之前,在完成第一次尝试之前发生的。
您可以在日志中看到,关闭连接后,逻辑继续并完成所有尝试,没有任何问题。
日志中没有任何关于连接关闭的原因,甚至 Fastify 声明的 onError 钩子也没有。
Axios 也没有。我猜是否有任何超时会引发异常并被记录。
重要提示
请注意,如果我更改 waitBeforeAttempt 实现以实现忙等待而不是 setTimeout,则不会断开连接,即:
function waitBeforeAttempt() {
const start = new Date();
let now;
while (true) {
now = new Date();
if (now - start >= 15000) {
break;
}
}
}
我是否做错了什么导致连接断开?也许 15 秒的等待时间太长了?我通过 Puppetter 在代码中设置了其他 setTimeout(与我的实现相同),但似乎没有引起问题。
只是回答我自己的问题。结果证明问题与等待或超时无关。
当 Node.js 服务在本地 运行 时,这不会发生,只有当 运行 在 Kubernets + Nginx 上时才会间歇性发生。
Nginx 只是在没有任何明显原因的情况下重新启动。
Nginx 已更新,问题不再出现。
我在使用 Fastify 的 Node.js 服务器上遇到问题。
在请求执行期间的某个时刻,服务器似乎正在关闭连接并且客户端收到套接字挂起错误。
服务器中的逻辑是:
- Fastify 客户端调用服务。
- 服务使用 Axios 发送 HTTP 请求以获取某些信息。该服务实现了重试机制,每次重试后,它会等待 15 秒以确保信息可用。
代码如下:
Fastify 服务器:
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();
})
服务:
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 秒之后,在通过 Axios 调用之前,在完成第一次尝试之前发生的。
您可以在日志中看到,关闭连接后,逻辑继续并完成所有尝试,没有任何问题。
日志中没有任何关于连接关闭的原因,甚至 Fastify 声明的 onError 钩子也没有。
Axios 也没有。我猜是否有任何超时会引发异常并被记录。
重要提示
请注意,如果我更改 waitBeforeAttempt 实现以实现忙等待而不是 setTimeout,则不会断开连接,即:
function waitBeforeAttempt() {
const start = new Date();
let now;
while (true) {
now = new Date();
if (now - start >= 15000) {
break;
}
}
}
我是否做错了什么导致连接断开?也许 15 秒的等待时间太长了?我通过 Puppetter 在代码中设置了其他 setTimeout(与我的实现相同),但似乎没有引起问题。
只是回答我自己的问题。结果证明问题与等待或超时无关。
当 Node.js 服务在本地 运行 时,这不会发生,只有当 运行 在 Kubernets + Nginx 上时才会间歇性发生。
Nginx 只是在没有任何明显原因的情况下重新启动。
Nginx 已更新,问题不再出现。