# node负载均衡RoundRobin
# 核心代码
RoundRobinHandle.prototype.distribute = function(err, handle) {
this.handles.push(handle);
const worker = this.free.shift();
if (worker) this.handoff(worker);
};
// 发送消息和handle给对应worker进程
RoundRobinHandle.prototype.handoff = function(worker) {
if (worker.id in this.all === false) {
return; // 如果 worker 已经被关了
}
const handle = this.handles.shift();
if (handle === undefined) {
this.free.push(worker); // 再次添加到空闲子进程队列
return;
}
const message = { act: 'newconn', key: this.key };
sendHelper(worker.process, message, handle, (reply) => {
if (reply.accepted)
handle.close();
else
this.distribute(0, handle); // 当前 Worker 正在关闭,准备发送给另一个 worker
this.handoff(worker);
});
};
# 重要概念
- distribute: 负责筛选出处理请求的子进程
- this.handles: 存放客户端待处理的请求
- this.free: 存放空闲子进程
- handoff: 拿出排队中的客户端请求,进行任务处理
# 流程
- 首先 request 进来。
- 执行 distribute,把请求在 handles 里存放起来,再从 free 里取出空闲子进程,如果有空闲子进程,就执行 handoff 给他发消息。
- handoff,先获取排队中的客户端请求,通过IPC通道发送句柄,等消息返回。当子进程返回正在处理请求的消息时,它会继续执行 handoff 函数,分配请求给这个子进程,不管该子进程上次请求是否处理完成(node的异步特性和事件循环可以让单进程处理多请求)。
- 一旦主进程没有缓存的客户端请求时(handles为空),便会将当前子进程加入free空闲队列,等待主进程的下一步调度。这就是cluster模式的RoundRobin调度策略,每个子进程的处理逻辑都是一个闭环,直到主进程缓存的客户端请求处理完毕时,该子进程的处理闭环才被打开。
← Node实践 node进程间通信方式 →