【问题标题】:NodeJS - express server, pm2 cluser and nginx balancing - multiple threadsNodeJS - express server、pm2 cluser 和 nginx 平衡 - 多线程
【发布时间】:2018-05-31 20:13:20
【问题描述】:

我正在尝试设置快速服务器以侦听多个线程。我已经使用 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;
    }

}

到目前为止一切顺利。我的环境:

  • 节点 v 10.3.0
  • cpu cores 8,但我只使用了 4 个实例

好的,开始申请:

┌──────────┬────┬─────────┬───────┬────────┬─────────┬────────┬─────┬───────────┬───────────────┬──────────┐
│ 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

正如我们所见,它正确地平衡了对节点的请求,但在某个地方出现了停滞。如何强制它并行运行?

【问题讨论】:

  • 平行是什么意思??在这里,您将获得成功的结果。根据您的要求,如果请求停止,则不会记录 console.log("请求时间:" + (stopTime - startTime));
  • 我的意思是请求在队列中解决而不是并行解决(但是有异步,为什么?)。他们在某个地方被对方挡住了。我得到了成功的结果,但我没有在 ~700 毫秒(最长的响应)内得到所有响应,而是在 >2 秒后得到它们
  • 你想一次调用所有节点服务器吗?

标签: node.js multithreading express nginx


【解决方案1】:

事实证明,一切都很好。 问题出在浏览器上。当浏览器发送相同的 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}`));

【讨论】:

    【解决方案2】:

    您确定请求真的在所有内核上吗?我的意思是要对此进行测试,您将需要使用同步功能。如果您使用异步方法,即使在一个线程上,请求仍将异步完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 2015-08-14
      • 1970-01-01
      • 2015-06-15
      • 1970-01-01
      • 2016-05-22
      • 2020-08-17
      • 1970-01-01
      相关资源
      最近更新 更多