编码
我有一个集群节点应用程序,它监听 TCP 流量并将二进制数据解析为 JSON 格式。
但这里有一个问题:所有传入流量都来自一个持久连接。
据我了解,集群将通过在工作人员之间分配新的套接字来平衡单个端口上的负载,但是没有本地方法可以在工作人员之间分配单个套接字的负载。
为此,我设置了集群主机以接受传入连接并对消息进行分段。然后,它以循环方式将消息显式传递给集群工作人员。当负责分割消息的流发出一条新消息时,它只需使用集群消息 APIsend
将消息发送到行中的下一个 Worker/parser:
// (cluster.isMaster === true)
var gateway = new Gateway(config.gateway.port, config.gateway.host);
var nextWorker = 1;
gateway.on('message', function roundRobin (msg) {
var workers = cluster.workers;
var numWorkers = Object.keys(workers).length;
workers[nextWorker].send(msg);
if (++nextWorker > numWorkers) {
nextWorker = 1; // else, it's prefix incremented
}
});
for (w in cluster.workers) {
cluster.workers[w].on('message', gateway.respond.bind(gateway));
}
Workers 解析消息,使用它发出 HTTP 请求,然后使用集群send
API 响应gateway
(上面的最后一个代码块)。
问题
将系统置于负载下时,我会遇到奇怪且不可预测的延迟模式。所有 CPU/内存/网络测量都是合理的,并不表示基础设施瓶颈。
问题
如您所见,工作在工作人员之间平均分配,而与给定工作人员的实际吞吐量无关。我的预感是,这就是导致延迟峰值的原因——也许某个地方,某个工作人员正在备份。
有什么方法可以在原则上或经验上证实这一点?也许这只是一厢情愿,但似乎该方法应该只是平均化,不需要工人拉式算法。(这似乎特别棘手,因为我无法推断哪个是认为工作人员空闲的最佳时间——在它完成解析之后?在它收到 HTTP 响应之后?在它向网关发送响应之后?)
我只是对 CPU 调度知之甚少,不知道我是否在追逐红鲱鱼,或者这是否是一个糟糕的算法,肯定会造成麻烦。(如果是这样,任何关于如何改进它的想法都将不胜感激。)