DigitalOcean上Node.js Express+GraphQL Yoga请求5分钟超时问题求助
解决DigitalOcean上长请求5分钟超时问题
以下是针对长请求(超5分钟)失败问题的排查方向和解决方案:
1. 调整DigitalOcean Droplet的内核TCP超时设置
DigitalOcean Droplet默认存在TCP连接空闲超时(通常为300秒/5分钟),会主动断开长时间无数据传输的连接。可通过修改内核参数延长超时:
临时生效(重启后失效):
sysctl -w net.ipv4.tcp_keepalive_time=300 sysctl -w net.ipv4.tcp_keepalive_intvl=60 sysctl -w net.ipv4.tcp_keepalive_probes=10上述设置让系统每300秒发送一次keepalive探测包,每次间隔60秒,重试10次后才断开,总覆盖时长可达900秒(15分钟)。
永久生效:
将以下内容写入/etc/sysctl.conf文件末尾:net.ipv4.tcp_keepalive_time=300 net.ipv4.tcp_keepalive_intvl=60 net.ipv4.tcp_keepalive_probes=10执行
sysctl -p使配置立即生效。
2. 补全Nginx的全局超时配置
仅在location块设置代理超时不够,需在http块补充全局超时参数:
http { # 客户端请求头/体的超时时间 client_header_timeout 5400s; client_body_timeout 5400s; # 服务器发送响应的超时时间 send_timeout 5400s; server { location / { proxy_pass http://feat/graphql; proxy_set_header Connection 'keep-alive'; proxy_read_timeout 5400s; proxy_send_timeout 5400s; proxy_http_version 1.1; chunked_transfer_encoding off; proxy_buffering off; proxy_cache off; # 添加keepalive超时 proxy_keepalive_timeout 5400s; } } }
修改后重启Nginx:sudo systemctl restart nginx
3. 确认应用层全链路超时
若使用Node.js+GraphQL服务,需补充以下配置:
GraphQL服务独立超时(以Apollo Server为例):
const { ApolloServer } = require('@apollo/server'); const server = new ApolloServer({ typeDefs, resolvers, // 设置resolver超时为10分钟 timeout: 1000 * 60 * 10, });Socket层keepalive设置:
const server = app.listen(port, () => { console.info(`Server is running on http://${host}:${port}/graphql`); }).setTimeout(1000 * 60 * 10); server.on('connection', (socket) => { // 每60秒发送一次keepalive探测包 socket.setKeepAlive(true, 60000); socket.setTimeout(1000 * 60 * 10); });
4. 调整客户端侧超时限制
- Postman:默认请求超时为300秒,需手动修改:打开「Settings」→「General」,将「Request timeout」改为600秒或更大值。
- 浏览器:大部分浏览器HTTP请求超时限制在5分钟左右,无法直接修改。建议采用两种方案:
- 将长任务拆分为异步任务:先返回任务ID,前端轮询接口获取结果。
- 使用WebSocket替代普通HTTP请求,自定义连接超时。
5. 验证连接状态
修改配置后,用ss -ti命令查看TCP连接的超时参数,确认keepalive设置生效:
ss -ti dst <你的应用IP> sport = :80
查看输出中的keepalive字段,确认参数与设置一致。
内容的提问来源于stack exchange,提问作者Anjul Saini
相关产品推荐
相关产品推荐

