[英]node.js staggering keep alives to large amount of tcp clients
I'm trying to send keep alives from a server to a bunch of tcp clients. 我正在尝试从服务器向一堆tcp客户端发送保持活动状态。 To reduce the server load on the responses, I want to spread the keep alives apart. 为了减少服务器在响应中的负载,我想分散保持活动。
If I have 3000 tcp clients, and 60s keep alive interval, I need to stagger keep alive messages over the 60s and send 50 keep alives every second. 如果我有3000个tcp客户端,并且60s保持活动间隔,则需要在60s上错开保持活动消息,并每秒发送50个保持活动。
Assumptions: 假设:
Currently, my thought is to store my tcp connections as a standard javascript object, with some id mapping to a particular the connection itself. 目前,我的想法是将tcp连接存储为标准的javascript对象,并将一些id映射到特定的连接本身。 Then, each second, I get the array of keys of this object, and send keep alives to some portion of these. 然后,每秒钟,我获得该对象的键数组,并向其中的某些部分发送保持活动状态。
Is this a good approach? 这是一个好方法吗? Are there better approaches or other things I should consider? 是否有更好的方法或其他我应该考虑的东西?
Example code for my initial stab at the problem: 我最初遇到问题时的示例代码:
var KEEP_ALIVE_INTERVAL = 1000; // time between groups
var KEEP_ALIVE_CYCLE = 3; // number of groups
var tcp_conns = {
a:"a",
b:"b",
c:"c",
d:"d",
e:"e",
f:"f",
g:"g",
h:"h",
i:"i"
};
var intervalCounter = 0;
setInterval(function() {
console.log("sending keep alives intervalCounter="+intervalCounter);
var numConns = Object.keys(tcp_conns).length;
var connFactor = Math.ceil( numConns / KEEP_ALIVE_CYCLE );
var lowerLimit = connFactor*intervalCounter-1;
var upperLimit = connFactor*(intervalCounter+1);
console.log("connFactor="+connFactor+", limits=["+lowerLimit+","+upperLimit+"]");
// Is this even async???
var keys = Object.keys(tcp_conns)
for (var i = 0; i < keys.length; i++) {
if(i>lowerLimit && i<upperLimit){
var key = keys[i]
var val = tcp_conns[key]
console.log(" id="+key+" => "+val);
}
}
intervalCounter++;
if(intervalCounter==KEEP_ALIVE_CYCLE){
intervalCounter=0;
}
}, KEEP_ALIVE_INTERVAL);
Rather than explicitly managing a collection containing all the connections, I'd send keep-alives randomly every 45s to 75s. 我不是显式管理包含所有连接的集合,而是每45s到75s随机发送一次keep-alive。 This way, keep-alives will be spread over time. 这样,保持活动将随着时间的流逝而扩展。 I'm not sure that the following code works as-is, but you'll get the basic idea. 我不确定以下代码是否可以按原样工作,但是您将了解基本概念。
Here's the code: 这是代码:
var KEEP_ALIVE_TIMEOUT = 120*1000,
MIN_KEEP_ALIVE = 45*1000,
MAX_KEEP_ALIVE = 75*1000;
function randomInt(min, max) {
return Math.random()*(max - min) + min;
}
net.createServer(function(conn) {
function ping() {
var keepAliveTimer = setTimeout(function() {
conn.destroy();
console.log('timeout !');
}, KEEP_ALIVE_TIMEOUT);
conn.write('PING\r\n');
conn.on('data', function onData(chunk) {
if(chunk.toString() !== 'PONG\r\n')
return handleSomethingElse();
clearTimeout(keepAliveTimer);
conn.removeListener('data', onData);
setTimeout(ping, randomInt(MIN_KEEP_ALIVE, MAX_KEEP_ALIVE));
});
}
ping();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.