具有 pm2 的节点集群每隔一个请求排队
Node clusters with pm2 queues every other request
我正在使用 pm2 来管理对我的 API 的并发请求,到目前为止一切顺利,我已经设法让它工作了。
我的api只有一条路线。每个请求需要 1-2 分钟才能完全解决并发回响应。一旦我发出第一个请求,我就可以在 pm2 日志中看到该请求已被接受,但是如果我向同一路由发出第二个请求,它就会排队,并且只有在第一个请求完成后才会被处理。
只有在第二个请求在队列中时我向同一路由发出第三个请求时,才会调用另一个工作人员并接受第三个请求,第二个工作人员会留在队列中,直到第一个请求得到解决。
我希望我说清楚了
第一个请求被一个工人迅速接受,第二个请求排队,第三个请求也被另一个工人迅速接受,第四个排队,第五个被接受,第六个排队等。
我有 24 个可用的工人。
这是我非常简单的服务器:
const express = require('express');
const runner = require('./Rrunner2')
const moment = require('moment');
const bodyParser = require('body-parser');
const app = express();
app.use(express.json({limit: '50mb', extended: true}));
app.use(bodyParser.json())
app.post('/optimize', (req, res) => {
try{
const req_start = moment().format('DD/MM/YYYY h:mm a');
console.log('Request received at ' + req_start)
console.log(`Worker process ID - ${process.pid} has accepted the request.`);
const data = req.body;
const opt_start = moment().format('DD/MM/YYYY h:mm a')
console.log('Optimization started at ' + opt_start)
let result = runner.optimizer(data);
const opt_end = moment().format('DD/MM/YYYY h:mm a')
console.log('Optmization ended at ' + opt_end)
const res_send = moment().format('DD/MM/YYYY h:mm a');
console.log('Response sent at ' + res_send)
return res.send(result)
}catch(err){
console.error(err)
return res.status(500).send('Server error.')
}
});
const PORT = 3000;
app.listen(PORT, () => console.log(`Server listening port ${PORT}.`))
我的 PM2 生态系统文件是:
module.exports = {
apps : [{
name: "Asset Optimizer",
script: "server.js",
watch: true,
ignore_watch: ["optimizer", "outputData", "Rplots.pdf", "nodeSender.js", "errorLog"],
instances: "max",
autorestart: true,
max_memory_restart: "1G",
exec_mode: "cluster",
watch_options:{
"followSymlinks": false
}
}
]}
我使用 pm2 start ecosystem.config.js
启动服务器
一切正常,但这个队列问题让我抓狂。我尝试过很多肮脏的方法,包括拆分路由、拆分服务器。没有任何成功。
即使你不知道这个问题的答案,也请给我一些关于如何克服这个问题的想法。非常感谢。
更新
好的,我已经设法通过设置使它与本机集群模块一起工作:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
cluster.schedulingPolicy = cluster.SCHED_RR;
但是一旦我尝试让 pm2 启动服务器,它就不再起作用了。
有没有可能让pm2接受Round Robin appproach
P.S.: 我正在使用windows,在节点文档中发现默认情况下没有设置它是onlu平台。
此问题唯一可行的解决方案是将 nginx 实施为反向代理和负载平衡器。
我使用的是 nginx 1.18.0,这是让它工作的配置文件。
如果有人遇到这个问题,nginx + pm2 是可行的方法。
如果有人遇到这个问题,很高兴进一步澄清。它给了我很多工作。
worker_processes 5;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
upstream expressapi {
least_conn;
server localhost:3000;
server localhost:3001;
server localhost:3002;
server localhost:3003;
server localhost:3004;
}
sendfile on;
keepalive_timeout 800;
fastcgi_read_timeout 800;
proxy_read_timeout 800;
server {
listen 8000;
server_name optimizer;
location / {
proxy_pass http://expressapi/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
如上所述,问题不在于PM2。 Pm2 只是处理发送给它的请求。问题出在发送请求的上层,也就是 nignx。
我正在使用 pm2 来管理对我的 API 的并发请求,到目前为止一切顺利,我已经设法让它工作了。
我的api只有一条路线。每个请求需要 1-2 分钟才能完全解决并发回响应。一旦我发出第一个请求,我就可以在 pm2 日志中看到该请求已被接受,但是如果我向同一路由发出第二个请求,它就会排队,并且只有在第一个请求完成后才会被处理。 只有在第二个请求在队列中时我向同一路由发出第三个请求时,才会调用另一个工作人员并接受第三个请求,第二个工作人员会留在队列中,直到第一个请求得到解决。 我希望我说清楚了
第一个请求被一个工人迅速接受,第二个请求排队,第三个请求也被另一个工人迅速接受,第四个排队,第五个被接受,第六个排队等。
我有 24 个可用的工人。
这是我非常简单的服务器:
const express = require('express');
const runner = require('./Rrunner2')
const moment = require('moment');
const bodyParser = require('body-parser');
const app = express();
app.use(express.json({limit: '50mb', extended: true}));
app.use(bodyParser.json())
app.post('/optimize', (req, res) => {
try{
const req_start = moment().format('DD/MM/YYYY h:mm a');
console.log('Request received at ' + req_start)
console.log(`Worker process ID - ${process.pid} has accepted the request.`);
const data = req.body;
const opt_start = moment().format('DD/MM/YYYY h:mm a')
console.log('Optimization started at ' + opt_start)
let result = runner.optimizer(data);
const opt_end = moment().format('DD/MM/YYYY h:mm a')
console.log('Optmization ended at ' + opt_end)
const res_send = moment().format('DD/MM/YYYY h:mm a');
console.log('Response sent at ' + res_send)
return res.send(result)
}catch(err){
console.error(err)
return res.status(500).send('Server error.')
}
});
const PORT = 3000;
app.listen(PORT, () => console.log(`Server listening port ${PORT}.`))
我的 PM2 生态系统文件是:
module.exports = {
apps : [{
name: "Asset Optimizer",
script: "server.js",
watch: true,
ignore_watch: ["optimizer", "outputData", "Rplots.pdf", "nodeSender.js", "errorLog"],
instances: "max",
autorestart: true,
max_memory_restart: "1G",
exec_mode: "cluster",
watch_options:{
"followSymlinks": false
}
}
]}
我使用 pm2 start ecosystem.config.js
一切正常,但这个队列问题让我抓狂。我尝试过很多肮脏的方法,包括拆分路由、拆分服务器。没有任何成功。
即使你不知道这个问题的答案,也请给我一些关于如何克服这个问题的想法。非常感谢。
更新
好的,我已经设法通过设置使它与本机集群模块一起工作:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
cluster.schedulingPolicy = cluster.SCHED_RR;
但是一旦我尝试让 pm2 启动服务器,它就不再起作用了。 有没有可能让pm2接受Round Robin appproach
P.S.: 我正在使用windows,在节点文档中发现默认情况下没有设置它是onlu平台。
此问题唯一可行的解决方案是将 nginx 实施为反向代理和负载平衡器。
我使用的是 nginx 1.18.0,这是让它工作的配置文件。 如果有人遇到这个问题,nginx + pm2 是可行的方法。 如果有人遇到这个问题,很高兴进一步澄清。它给了我很多工作。
worker_processes 5;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
upstream expressapi {
least_conn;
server localhost:3000;
server localhost:3001;
server localhost:3002;
server localhost:3003;
server localhost:3004;
}
sendfile on;
keepalive_timeout 800;
fastcgi_read_timeout 800;
proxy_read_timeout 800;
server {
listen 8000;
server_name optimizer;
location / {
proxy_pass http://expressapi/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
如上所述,问题不在于PM2。 Pm2 只是处理发送给它的请求。问题出在发送请求的上层,也就是 nignx。