nodejs 请求接口在高并发下耗时很大,而单个请求非常快

2016-11-03 11:30:34 +08:00
 tofishes

情况: request.js 库请求接口, express.js 做 server ,实现了 curl http://localhost:8080/proxy-api 本地一个地址,在 router 里用 request.js 请求接口,统计了一下请求耗时,单个请求耗时很低,如下:

get http://ip:9190/user/getUserInfo 13 ms

然后分别使用 webbench 和 ab 做并发测试,并发 500 ,发现接口有非常大的耗时。

# 测试命令
ab -n 1000 -c 200 -r http://localhost:8080/proxy-api
webbench -t 10 -c 500 http://localhost:8080/proxy-api
# 截取部分响应耗时:
get http://ip:9190/user/getUserInfo 2019 ms
cost time:  2020
get http://ip:9190/user/getUserInfo 2062 ms
cost time:  2062
get http://ip:9190/user/getUserInfo 2064 ms
cost time:  2065
get http://ip:9190/user/getUserInfo 2063 ms
cost time:  2063
get http://ip:9190/user/getUserInfo 2062 ms
cost time:  2063
get http://ip:9190/user/getUserInfo 2063 ms
cost time:  2063
get http://ip:9190/user/getUserInfo 2061 ms
cost time:  2062
get http://ip:9190/user/getUserInfo 2063 ms
cost time:  2064
get http://ip:9190/user/getUserInfo 2063 ms
...
...
get http://ip:9190/user/getUserInfo 1362 ms
cost time:  1362
get http://ip:9190/user/getUserInfo 1361 ms
cost time:  1362
get http://ip:9190/user/getUserInfo 1362 ms
cost time:  1362
get http://ip:9190/user/getUserInfo 1362 ms
cost time:  1362
get http://ip:9190/user/getUserInfo 1362 ms
cost time:  1362
get http://ip:9190/user/getUserInfo 1363 ms
cost time:  1363
get http://ip:9190/user/getUserInfo 1362 ms
cost time:  1362
...
...
get http://ip:9190/user/getUserInfo 1006 ms
cost time:  1006
get http://ip:9190/user/getUserInfo 627 ms
cost time:  628
get http://ip:9190/user/getUserInfo 629 ms
cost time:  629
get http://ip:9190/user/getUserInfo 628 ms
cost time:  629
get http://ip:9190/user/getUserInfo 1403 ms
cost time:  1403
get http://ip:9190/user/getUserInfo 1402 ms

请问哪位朋友有没有解决这类问题的经验?

23989 次点击
所在节点    Node.js
46 条回复
enenaaa
2016-11-03 14:56:44 +08:00
不懂 node 。
考虑一下系统和网络性能,服务端 tcp 监听端口有接受队列, 频繁发起请求可能会有点耗时。
可以试一下在单个连接上测试
tofishes
2016-11-03 15:00:19 +08:00
@sherlocktheplant 简单代码已附言
xxxyyy
2016-11-03 15:42:52 +08:00
@tofishes 你试下用以下的代码测下,如果结果差别不大,可能是后端的问题了:

```
const http = require("http");

const server = http.createServer((req, res) => {
    setTimeout(function () {
        res.writeHead(200);
        res.end();
    }, Math.random() * 100);
});

server.listen(8888);
```

=============================
然后你上面贴出来的脚本也改成这样:
```
const request = require('request').defaults({
    pool: { maxSockets: 5000 }
});

const c = 500;
const api = 'http://localhost:8888';

const costs = [];
function doGet(i) {
    const start = Date.now();
    const index = i;
    request.get(api, () => {
        const end = Date.now() - start;
        costs.push(`${index}: ${end}ms`);
        if (costs.length === c) {
            console.log(costs.join("\n"));
        }
    });
}

for (let i = 0; i < c; i++) {
    doGet(i);
}
```
wxx199101046
2016-11-03 15:50:42 +08:00
用上 pm2 结果会不会不一样?
Arrowing
2016-11-03 16:26:14 +08:00
用利用多进程多核的特性没?
我用的 PM2 测的,服务器是 CPU:Intel(R) Xeon(R) E5-2640 0 @ 2.50GHz 共 24 核 MEM:32G

并发数 TPS 响应时间 CPU 成功数 写文件 丢失率 时间
5000 10331.5 0.446 55% 19327244 19323366 0.02% 1 小时
10000 10392.1 0.86 55% 23631728 23626987 0.02% 1 小时
2000 9673.45 0.198 55% 416065314 415983941 0.0195% 11 小时+
tofishes
2016-11-03 18:34:32 +08:00
@Arrowing 没有实用多核多进程
tofishes
2016-11-03 18:38:57 +08:00
@xxxyyy 用了你的代码,用时变的比较均匀,截取最长耗时的和最短耗时,如下:

```
# 最短耗时:
127: 235ms
34: 285ms
62: 283ms
72: 283ms
97: 283ms
55: 289ms
89: 286ms
124: 283ms

# 最长耗时:
279: 611ms
267: 612ms
437: 600ms
467: 599ms
421: 608ms
417: 609ms
436: 608ms
479: 606ms
461: 607ms
443: 608ms
448: 607ms
438: 609ms
430: 609ms
```
tofishes
2016-11-03 18:45:18 +08:00
@wxx199101046 用 pm2 简单部署了下,结果还是一样
sampeng
2016-11-03 18:51:11 +08:00
为啥不把 node 换成 nginx 试试呢?直接 nginx 反向代理试试昂。。。
tofishes
2016-11-03 19:44:28 +08:00
@sampeng 反向代理不是根本目的, node 做页面渲染的,转发接口这是其中一部分,不是 ningx 干的事儿。
hxsf
2016-11-03 20:02:28 +08:00
mark 等下电脑回复
zhuangzhuang1988
2016-11-03 20:57:57 +08:00
xxxyyy
2016-11-03 21:05:50 +08:00
@tofishes 这相差还是很大的,或许你可以用 wireshark 抓包,然后统计下时间,看能不能发现问题。
tofishes
2016-11-04 09:45:12 +08:00
@zhuangzhuang1988 基于 Visual Studio ? osx 系统比较尴尬。。。我安装个虚拟机吧
sampeng
2016-11-04 10:52:04 +08:00
@tofishes nonono,问题是你需要确认是 node 的问题还是转发的问题。没问题就可以忽略掉 api 的故障了。。
我在使用 nodejs 的过程中转发发现也很诡异,经常堵得严严实实的。。。
tofishes
2016-11-04 11:17:05 +08:00
@sampeng 是这样的,发起 1000 个请求,并发为 1 ,每次耗时都很低,但一旦并发数加大,加到 10 , 50 , 100 ,耗时就随之增加,可以认为是并发下的问题。
tofishes
2016-11-04 11:17:45 +08:00
@zhuangzhuang1988 了解了一下, VS Code 有 mac 版本
zhuangzhuang1988
2016-11-04 11:28:25 +08:00
@tofishes vscode 没 profile 功能,记得
zhuangzhuang1988
2016-11-04 13:56:15 +08:00
而且 windows 上安装 nodejs 后支持这个
tofishes
2016-11-09 10:19:16 +08:00
@Arrowing 服务器 24 核,性能不要太好。想问下,你用的测试软件是什么?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/317678

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX