首页 > 解决方案 > NodeJS - express server、pm2 cluser 和 nginx 平衡 - 多线程

问题描述

我正在尝试设置快速服务器以侦听多个线程。我已经使用 pm2 在端口3000、3001、3002、3003上设置应用程序,但请求仍在等待对方...

表达应用index.js

const express = require('express')
const axios = require('axios')
const app = express()

app.get('/', async (req, res) => {
    console.log('-----> GOT REQUEST -> ' + (new Date()).getTime());
    let resp = await axios.get("here some correct http get");
    res.send("Hello world!")
    console.log('    Response time: ' + (new Date()).getTime());
})

let instance  = +process.env.NODE_APP_INSTANCE || 0;
let port      = (+process.env.PORT || 3000) + instance;
app.listen(port, () => console.log('Example app listening on port ' + port))

所以每个实例都在另一个端口上。现在是 nginx 的时候了:

upstream test_upstream {
    least_conn;
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
}


server {
    listen 8000;

    location / {
        proxy_hide_header Access-Control-Allow-Origin;

        add_header Access-Control-Allow-Origin * always;

        proxy_hide_header Access-Control-Allow-Methods;
        add_header Access-Control-Allow-Methods "GET,POST,DELETE,PUT,OPTIONS" always;
        proxy_hide_header Access-Control-Allow-Headers;
        add_header Access-Control-Allow-Headers "Authorization, X-Requested-With, Content-Type" always;
        proxy_hide_header Access-Control-Allow-Credentials;
        add_header Access-Control-Allow-Credentials "true" always;

        if ($request_method = OPTIONS ) { # Allow CORS
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods "GET,POST,DELETE,PUT,OPTIONS";
            add_header Access-Control-Allow-Headers "Authorization, X-Requested-With, Content-Type";
            add_header Access-Control-Allow-Credentials "true" always;
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            add_header Allow GET,POST,DELETE,PUT,OPTIONS;
            return 200;
        }
        proxy_pass http://test_upstream;
    }

}

到目前为止,一切都很好。我的环境:

好的,开始申请:

┌──────────┬────┬─────────┬───────┬────────┬─────────┬────────┬─────┬───────────┬───────────────┬──────────┐
│ App name │ id │ mode    │ pid   │ status │ restart │ uptime │ cpu │ mem       │ user          │ watching │
├──────────┼────┼─────────┼───────┼────────┼─────────┼────────┼─────┼───────────┼───────────────┼──────────┤
│ index    │ 0  │ cluster │ 57069 │ online │ 6       │ 17m    │ 0%  │ 39.7 MB   │ administrator │ disabled │
│ index    │ 1  │ cluster │ 57074 │ online │ 6       │ 17m    │ 0%  │ 39.0 MB   │ administrator │ disabled │
│ index    │ 2  │ cluster │ 57091 │ online │ 6       │ 17m    │ 0%  │ 37.5 MB   │ administrator │ disabled │
│ index    │ 3  │ cluster │ 57097 │ online │ 6       │ 17m    │ 0%  │ 38.8 MB   │ administrator │ disabled │
└──────────┴────┴─────────┴───────┴────────┴─────────┴────────┴─────┴───────────┴───────────────┴──────────┘

现在是时候调用它了。我想同时发送多个请求:

async sendRequest() {
  const startTime = performance.now();
  console.log("Sending request");
  const els = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  const promises = els.map(() => axios.get("http://my_server_with_nginx:8000"));
  let results = await Promise.all(promises);
  console.log(results);
  const stopTime = performance.now();
  console.log("Time of request: " + (stopTime - startTime));
}

测试看起来像这样: 在此处输入图像描述

最后是节点应用程序日志:

0|index    | -----> GOT REQUEST -> 1527796135425
0|index    |     Response time: 1527796135572
1|index    | -----> GOT REQUEST -> 1527796135595
1|index    |     Response time: 1527796135741
2|index    | -----> GOT REQUEST -> 1527796135766
2|index    |     Response time: 1527796136354
3|index    | -----> GOT REQUEST -> 1527796136381
3|index    |     Response time: 1527796136522
0|index    | -----> GOT REQUEST -> 1527796136547
0|index    |     Response time: 1527796136678
1|index    | -----> GOT REQUEST -> 1527796136702
1|index    |     Response time: 1527796136844
2|index    | -----> GOT REQUEST -> 1527796136868
2|index    |     Response time: 1527796137026
3|index    | -----> GOT REQUEST -> 1527796137098
3|index    |     Response time: 1527796137238
0|index    | -----> GOT REQUEST -> 1527796137263
0|index    |     Response time: 1527796137395
1|index    | -----> GOT REQUEST -> 1527796137419
1|index    |     Response time: 1527796137560

正如我们所看到的,它正确地平衡了对节点的请求,但是某个地方已经停止了。如何强制它并行运行?

标签: node.jsmultithreadingexpressnginx

解决方案


事实证明,一切都很好。问题出在浏览器上。当浏览器发送相同的 http get 请求时,它们会排队。要改变这一点,我必须改变调用:

const els = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const promises = els.map(() => axios.get("http://my_server_with_nginx:8000"));

对此:

const els = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const promises = els.map((el) => axios.get(`http://my_server_with_nginx:8000?number=${el}`));

推荐阅读