使用 nodejs 的 koa 框架作为后端服务时,为了充分利用服务器的核数,可以创建与cpu 数量相同的进程数。
创建多进程中可以使用 child_process 也可以使用 cluster。但是创建了多个进程后还需要考虑负载均衡。因为 cluster 中自己做了负载均衡的算法: round-robin(新连接由主进程接受,然后由它选择一个可用的 worker 把连接交出去,说白了就是轮转法)所以使用 cluster
这里创建进程时,让子进程监听同一端口。
可能会问:多个子进程监听同一端口会报错啊。
实际上,在 node 中进行了处理。当有多个进程监听端口时,Master 进程创建一个 Socket 并绑定监听到该目标端口,通过与子进程之间建立 IPC 通道之后,通过调用子进程的 send 方法,将 Socket(链接句柄)传递过去。端口只会被主进程绑定监听一次,但是主进程和子进程在建立 IPC 通信之后,发送 Socket 到子进程实现端口共享,在之后 Master 接收到新的客户端链接之后,通过负载均衡技术再转发到各 Worker 进程
下面是 koa 框架中创建多进程:
import Koa from "koa"; import route from "./router"; import cors from "@koa/cors"; import bodyParser from "koa-bodyparser"; import cluster from "cluster"; const numCPUs = require("os").cpus().length; if (cluster.isMaster) { for (var i = 0; i < numCPUs; i++) { cluster.fork(); } // 监听worker cluster.on("listening", function (worker, address) { console.log( "listening: worker " + worker.process.pid + ", Address: " + address.address + ":" + address.port + "," + address.addressType ); }); // 监听worker退出事件,code进程非正常退出的错误code,signal导致进程被杀死的信号名称 cluster.on("exit", function (worker, code, signal) { console.log( "工作进程 %d 关闭 (%s)(%s). 重启中...", worker.process.pid, signal || code ); cluster.fork(); }); } else { const app = new Koa(); app.use(cors()); app.use(bodyParser()); route(app); app.listen(3000); }
我这里使用了 typescript 所以可以使用 import 和 require 混合搭配。如果编写 js 的话把 import 都改成 require 就好了。