如何让部署在cPanel上的Node.js服务器保持长连接?
Node.js长连接在Namecheap cPanel上5分钟断开,无法维持12小时以上
我在Namecheap的cPanel上部署了Node.js服务器,功能是监听HTTP请求,建立连接后向客户端推送当前连接数和时间信息,同时每秒向Firebase发送时间戳。但现在连接总会在5分钟左右断开,达不到维持12小时以上的需求。
我已经试过这些方法,但都没用:
- 调整
server.keepAliveTimeout、server.headersTimeout、server.setTimeout为超大值或0 - 在连接实例(
sokk)上设置相同的超时参数 - 配置Cron Jobs定期发起请求
- 升级到商务主机
我的定时任务只有在连接存续期间才会运行,所以必须解决长连接维持的问题。
附服务器代码:
const https = require('https'); const http = require('http'); http.globalAgent.keepAlive = true; //for persistant connections (last long connections) const express = require("express"); const app = express(); const server = http.createServer(function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); setInterval(() => { server.getConnections(function(error, count) { res.write(count + ' ' + new Date() + "\n"); }); }, 60000); }, app).listen(); server.on("connection", function(sokk) { sokk.keepAliveTimeout = 86400000 + 1000; sokk.headersTimeout = 86400000 + 2000; setInterval(() => { rootRef.child("Servers/Server").child("conn").set(Date.now()); }, 1000); sokk.on("data", data => { console.log(data); }); console.log("A new connection was made by a client."); }); // server.setTimeout(86400000); // A value of 0 will disable the timeout behavior on incoming connections: https://nodejs.org/dist/latest-v6.x/docs/api/all.html#http_request_settimeout_timeout_callback // This is the important stuff server.keepAliveTimeout = 86400000 + 1000; server.headersTimeout = 86400000 + 2000;
解决方案
1. 调整cPanel/Apache反向代理超时
Namecheap的cPanel主机默认通过Apache做反向代理转发Node.js请求,Apache默认Timeout和ProxyTimeout是300秒(5分钟),这大概率是连接断开的核心原因:
- 联系Namecheap客服,要求将这两个参数调整为43200秒(12小时)
- 若主机允许自定义
.htaccess,添加以下配置:Timeout 43200 ProxyTimeout 43200
2. 修复Node.js代码的问题
你的代码存在内存泄漏、未处理连接关闭等隐患,修改后示例:
const http = require('http'); const express = require("express"); const app = express(); // 全局Agent配置 http.globalAgent.keepAlive = true; http.globalAgent.keepAliveMsecs = 43200000; const server = http.createServer(function(req, res) { // 添加keep-alive响应头 res.writeHead(200, { 'Content-Type': 'text/plain', 'Connection': 'keep-alive', 'Keep-Alive': 'timeout=43200, max=1000' }); // 定时推送数据的定时器 const pushInterval = setInterval(() => { server.getConnections(function(error, count) { if (error) { console.error('获取连接数失败:', error); clearInterval(pushInterval); res.end(); return; } // 确保连接未断开再写入 if (!res.writableEnded) { res.write(`${count} ${new Date()}\n`); res.flushHeaders(); // 强制刷新缓冲区,避免数据积压 } else { clearInterval(pushInterval); } }); }, 60000); // 监听连接关闭,清理定时器 res.on('close', () => { clearInterval(pushInterval); console.log('客户端连接关闭,清理推送定时器'); }); // 处理响应错误 res.on('error', (err) => { console.error('响应出错:', err); clearInterval(pushInterval); }); }, app).listen(); // 服务器级别超时配置 server.keepAliveTimeout = 43200000 + 1000; server.headersTimeout = 43200000 + 2000; server.setTimeout(43200000); server.on("connection", function(socket) { // 设置socket超时 socket.setTimeout(43200000); socket.keepAliveTimeout = 43200000 + 1000; socket.headersTimeout = 43200000 + 2000; // 每个连接对应一个Firebase定时器,连接断开时清理 const firebaseInterval = setInterval(() => { if (!socket.destroyed) { rootRef.child("Servers/Server").child("conn").set(Date.now()); } else { clearInterval(firebaseInterval); } }, 1000); socket.on("data", data => { console.log(data.toString()); }); socket.on('close', () => { clearInterval(firebaseInterval); console.log('客户端连接断开,清理Firebase定时器'); }); socket.on('error', (err) => { console.error('socket出错:', err); clearInterval(firebaseInterval); }); console.log("新客户端连接建立"); });
3. 客户端侧配合
确保客户端请求携带Connection: keep-alive头,不要主动关闭连接。如果是浏览器端,建议用EventSource或WebSocket代替普通HTTP长连接——浏览器对普通HTTP长连接的超时限制更严格。
4. 检查防火墙/CDN限制
如果启用了Cloudflare等CDN或主机内置防火墙,这些服务通常也有默认连接超时(比如Cloudflare默认100秒),需要同步调整对应超时参数。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

