• Node负载能力测试


    需求很简单,就是提供一个服务接口收集端上传来的日志文件并保存,要求能承受的QPS为5000。

    以前从来都没考虑过Node服务的负载能力,用 koa + co-busboy 接受上传文件请求并用 fs 直接写文件开发完服务并用 pm2 进行进程管理,总觉得心里不踏实,便开始在服务器上,测试 Node 服务的负载能力。

    服务器信息:

    系统:CentOS release 6.7

    CPU:48核

    压测命令:(在另一台服务器上运行命令)

    siege -c 10 -b -t 1m -l test.log http://xxx.xxx.xxx.xxx:3001 > siege.log

    测试简单 Node 服务负载:(使用简陋的方法统计QPS的大概值)

    server.js

     1 let http = require('http');
     2 let count = 0,
     3     start_timestamp = new Date().getTime();
     4 
     5 let server = http.createServer((req, res) => {
     6     try {
     7         let cur_timestamp = new Date().getTime();
     8         count++;
     9         if (cur_timestamp - start_timestamp >= 1000) {
    10             console.log(count);
    11             start_timestamp = cur_timestamp;
    12             count = 0;
    13         }
    14         res.writeHead(200, {'Content-Type': 'text/plain'});
    15         res.end('hello world');
    16     } catch (e) {
    17         console.log(`err: ${e.message}`);
    18     }
    19 });
    20 server.listen(3001);
    21 console.log('run on 3001');

    压测结果:

    使用两台不同的服务器同时运行压测命令得到的结果:

    如图可看出在服务器上单进程 Node 服务的性能极限,那么换成 koa 再来测一下会有什么结果呢?

    server_koa.js

     1 const Koa = require('koa');
     2 const app = new Koa();
     3 
     4 let count = 0,
     5     start_timestamp = new Date().getTime();
     6 
     7 app.use(async (ctx) => {
     8     try {
     9         let cur_timestamp = new Date().getTime();
    10         count++;
    11         if (cur_timestamp - start_timestamp >= 1000) {
    12             console.log(count);
    13             start_timestamp = cur_timestamp;
    14             count = 0;
    15         }
    16         ctx.body = 'hello world';
    17     } catch (e) {
    18         console.log(`err ${e.message}`);
    19     }
    20 });
    21 
    22 app.listen(3001);
    23 console.log('run on 3001');

    看来用 Koa 的话对极限QPS的影响还是比较大的

    如果使用 pm2 管理简单服务,结果如何?

    左图为 pm2 使用 1 个实例,右图为使用 4 个实例,可以明显看到实例增加能大大提高程序负载能力,但是使用 2 台机器压测的结果却是这样:

    有点奇怪了,照理来说 4 个实例的处理能力怎么说加起来应该远超过 1w 才对,试着加大实例数量到 48,再用 2 台机器压测结果如下:

    提升的效果不是很让人满意,使用 3 台机器压测结果:

    即使在 48 核的服务器上开了 48 个进程来跑,极限 QPS 也止步 1w。值得注意的是在 48 核的服务器上用 pm2 来跑 server_koa.js,极限 QPS 与跑 server.js 相近,都是略小于 1w。这说明此时极限 QPS 已经不是制约在服务代码实现上,而应该从 Node 底层实现寻找答案,在网上找了半天找到这篇博客干货比较多:http://taobaofed.org/blog/2015/10/29/deep-into-node-1/  

    由于 Node 的文件 I/O、事件循环的通知是 Libuv 维护的线程池来操作,且默认线程池的大小是 4,那么通过修改线程池大小 UV_THREADPOOL_SIZE 会发生什么现象呢?在 server.js 最顶上添加代码:

    process.env.UV_THREADPOOL_SIZE = 64;

    压测结果如下:

    结果没有明显变化。这是因为 Linux 下,网络 I/O 采用的是 epoll 异步模型,不是通过线程池的方式处理。

    如何修改 epoll 的参数来提升极限QPS呢?

  • 相关阅读:
    QR code 乱谈(一)
    用JAVA实现数字水印(可见)
    ctf总结
    Unix/Linux常用命令
    C语言概述
    C语言发发展历史
    为什么要学习C语言
    计算机应用领域
    计算机发展趋势
    如何学习计算机
  • 原文地址:https://www.cnblogs.com/cqq626/p/7775196.html
Copyright © 2020-2023  润新知