我已经实现了Kafka消费者应用程序,我只是想知道我是否在pm2集群模式下运行此应用程序,所有内核是否会使用相同的消息或不同的消息?有没有办法可以验证它?并且在群集模式下运行此应用程序是否理想?我在集群模式下运行它的原因是因为我们的kafka产生了大量的消息。
目前,如果我在pm2集群模式下运行它,我们所有的内核都达到了100%的CPU使用率。它是否会发生这样的事情?
仅供参考:我正在使用https://www.npmjs.com/package/no-kafka
答案 0 :(得分:3)
所有核心都会使用相同的消息或不同的消息吗?有没有办法可以验证它?
这取决于您的主题配置+消费者配置。我们举一个例子。
目前,如果我在pm2集群模式下运行它,我们所有的内核都达到了100%的CPU使用率。它是否会发生这样的事情?
我并不熟悉no-kafka以及消息的处理方式。
但是检查一下,在获取下一批消息之前,库是否等待提交。
如果没有,您的进程可能会为消息创建太多处理程序。
答案 1 :(得分:3)
基于PM2的群集仅适用于网络服务器,因为群集进程共享传入网络端口并分发请求。
在您的情况下,数据源是消息订阅,必须手动将其分发到群集的工作进程。
因此,为了安全起见,主进程应该与数据源交互并将消息均匀地分发给工作进程,因此在外部,它似乎是单个使用者,但仍然可以在所有CPU上处理消息核心。
下面的示例演示了这种设置,不依赖于基于PM2的群集:
const cluster = require('cluster');
const _ = require('lodash');
const os = require('os');
// dispatch index
let dispatchIndex = 0;
/**
* Dispatches data to workers in a cyclic fashion
* @param {*} data - data to process
*/
function dispatch(data) {
// ensure master
if (!cluster.isMaster) {
throw new Error('Only master can dispatch');
}
// get worker ids, sorted
const workersIds = _.sortBy(_.keys(cluster.workers), _.identity);
// ensure at least one worker is available
if (workersIds.length < 1) {
throw new Error('No worker process alive');
}
// select next worker
dispatchIndex = dispatchIndex >= workersIds.length ? 0 : dispatchIndex;
const worker = cluster.workers[workersIds[dispatchIndex]];
dispatchIndex++;
// send data to worker
worker.send(data);
}
// Main Script
if (cluster.isMaster) {
// Setup master process
console.info(`Master ${process.pid} started.`);
// fork worker processes to match available CPUs
const numCpu = os.cpus().length;
for (let i = 0; i < numCpu; i++) {
cluster.fork();
}
// *** Get/Subscribe data from external source and dispatch to workers ***
setInterval(() => dispatch({ a: 'value' }), 1000);
} else if (cluster.isWorker) {
// Setup worker process
console.info(`Worker ${process.pid} started.`);
// *** handle dispatched data ***
process.on('message', (data) => {
console.info(`Data processed by ${process.pid}`);
});
}