Nest 项目目前可以链接云服务的 Mysql 服务

那么如果直接在云服务上部署 Nest 项目链接本地 Mysql 服务理应比 Serverless 性能好才对,遂我们采用 ab 压测一下,看看哪个部署更有性价比

目前有云服务器两台,一台上部署 Nest 项目和 Mysql 服务 (A 服务器), 一台安装 ab 用来测试 (B 服务器), 同时使用 serverless 部署的云函数通过内网链接该云服务器的 Mysql 服务

# 当前环境配置

  • A 服务器: 1 核 2GB 1Mbps 带宽 Linux Centos7.6
  • B 服务器: 4 核 4GB 8Mbps 带宽 Linux Centos7.6
  • Serverless 云函数配置: 500 并发 / 分钟

# 在 B 服务器安装 ab 压测工具

h
$ yum install httpd-tools -y

# A 服务器部署项目

# nginx 配置域名访问 Nest 项目

nginx 配置反向代理访问 9002 端口 (该服务器 9000 端口被 php 占用)

n
server {
    listen 80;
    server_name manager.aplus.pub;
    location / {
        proxy_pass http://127.0.0.1:9002;
        proxy_set_header Host $host:80;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }
}

# 使用 PM2 部署 Nest 项目

使用 pm2 部署 nest 项目为了监控占用机器性能等参数

h
$ pm2 start ./dist/main.js
$ pm2 monit

# 压测实验开始

# 实验前本地测试

项目部署好了,先在本地测试一下访问速度

就以 GET /api/options 作为今天的测试接口

先使用浏览器访问 http://manager.aplus.pub/api/options

压测数据

多次测试下来接口访问时间在 40-45 毫秒内,算是非常快了

接下来访问采用 Serverless 部署的项目 https://service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com/api/options

压测数据

多次测试下来接口访问时间在 70-100 毫秒之间,比直接在云服务器上部署的要慢了 1 倍!

这里怀疑是因为直接在云服务部署的服务直接访问到本地的 mysql 服务器,而云函数则要通过网络访问,虽然是内网,但是延迟加网络传输造成的时间差也是很多的.

再次测试 GET /api/hello 接口

使用浏览器访问 http://manager.aplus.pub/api/hello

响应时间依旧在 40-45 毫秒

使用浏览器访问 https://service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com/api/hello

响应时间最后稳定在 60-80 毫秒,差距不是太大了,响应时间大概是直接访问云服务器的 2 倍左右,性能尚可

# ab 压测

为了进一步验证使用 Serverless 的性能,使用 ab 压测工具来测试一下

首先对 A 云服务器进行压测 GET /api/options

首先来个 200 并发,2000 个请求

h
[root@VM-12-5-centos /]# ab -n 2000 -c 200 http://manager.aplus.pub/api/options
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking manager.aplus.pub (be patient)
Completed 200 requests
Completed 400 requests
Completed 600 requests
Completed 800 requests
Completed 1000 requests
Completed 1200 requests
Completed 1400 requests
Completed 1600 requests
Completed 1800 requests
Completed 2000 requests
Finished 2000 requests
Server Software:        nginx/1.19.6
Server Hostname:        manager.aplus.pub
Server Port:            80
Document Path:          /api/options
Document Length:        102 bytes
Concurrency Level:      200
Time taken for tests:   14.776 seconds
Complete requests:      2000
Failed requests:        0
Write errors:           0
Total transferred:      664000 bytes
HTML transferred:       204000 bytes
Requests per second:    135.36 [#/sec] (mean)
Time per request:       1477.567 [ms] (mean)
Time per request:       7.388 [ms] (mean, across all concurrent requests)
Transfer rate:          43.89 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        3   19 121.8      4    1007
Processing:     6  826 1426.8    403   13370
Waiting:        6  815 1431.8    395   13370
Total:          9  845 1428.8    420   13373
Percentage of the requests served within a certain time (ms)
  50%    420
  66%    628
  75%    664
  80%    928
  90%   1915
  95%   3337
  98%   6372
  99%   6715
 100%  13373 (longest request)

在压测时,A 服务器单核 cpu 占用率一直在 70% 左右,可以认为该服务器的一个高占用了

结果 QPS 达到 135/s,80% 的用户响应时间在 1S 以下,性能尚可,毕竟只有 1 核 2G,1MB 带宽的配置,相信带宽更多的话 QPS 还会更高

接下来对 Serverless 部署的云函数进行压测,也是 200 并发,2000 个请求

h
[root@VM-12-5-centos /]# ab -n 2000 -c 200 https://service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com/api/options
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com (be patient)
Completed 200 requests
Completed 400 requests
Completed 600 requests
Completed 800 requests
Completed 1000 requests
Completed 1200 requests
Completed 1400 requests
Completed 1600 requests
Completed 1800 requests
Completed 2000 requests
Finished 2000 requests
Server Software:        
Server Hostname:        service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128
Document Path:          /api/options
Document Length:        102 bytes
Concurrency Level:      200
Time taken for tests:   15.280 seconds
Complete requests:      2000
Failed requests:        607
   (Connect: 0, Receive: 0, Length: 607, Exceptions: 0)
Write errors:           0
Non-2xx responses:      607
Total transferred:      2020156 bytes
HTML transferred:       173043 bytes
Requests per second:    130.89 [#/sec] (mean)
Time per request:       1527.950 [ms] (mean)
Time per request:       7.640 [ms] (mean, across all concurrent requests)
Transfer rate:          129.11 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       12   46  42.9     29     261
Processing:     4  896 2909.6     29   15081
Waiting:        4  892 2910.1     28   15081
Total:         18  943 2927.3     64   15184
Percentage of the requests served within a certain time (ms)
  50%     64
  66%     89
  75%    106
  80%    110
  90%    912
  95%   6300
  98%  15151
  99%  15154
 100%  15184 (longest request)

这里发现个问题

Failed requests:607 , 错误链接数竟然达到 607 个,感觉很不正常,遂查看 Serverless 云函数日志,发现有一部分请求出现了错误

h
Error: Too many connections
    at Packet.asError (/var/user/node_modules/mysql2/lib/packets/packet.js:728:17)
    at ClientHandshake.execute (/var/user/node_modules/mysql2/lib/commands/command.js:29:26)
    at PoolConnection.handlePacket (/var/user/node_modules/mysql2/lib/connection.js:456:32)
    at PacketParser.onPacket (/var/user/node_modules/mysql2/lib/connection.js:85:12)
    at PacketParser.executeStart (/var/user/node_modules/mysql2/lib/packet_parser.js:75:16)
    at Socket.<anonymous> (/var/user/node_modules/mysql2/lib/connection.js:92:25)
    at Socket.emit (node:events:390:28)
    at addChunk (node:internal/streams/readable:315:12)
    at readableAddChunk (node:internal/streams/readable:289:9)
    at Socket.Readable.push (node:internal/streams/readable:228:10)

这是 Mysql 连接数达到上限了,查看 Mysql 的最大连接数只有 151, 改为 5000 继续进行压测实验

h
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+
1 row in set (0.03 sec)
mysql> set global max_connections=5000;
Query OK, 0 rows affected (0.00 sec)
mysql> exit

修改完 Mysql 的最大连接数限制之后继续进行压测发现还有 500 多 Failed requests , 怀疑是访问 Serverless 云函数时请求过多过快超过了它本身的并发限制,查看日志发现很多 StatusCode 429 的情况,果然是超出了限制

因为我的 Serverless 云函数是最便宜的套餐,只有 500 并发 / 分钟,我们之前的测试已经达到了 130 / 秒,肯定大大超过了限制

打开云函数控制台,发现有个设置 请求多并发

请求并发优势

在 IO 密集型场景中,如 Websocket 长连接业务,可减少计费执行时长,节省费用。

多个请求并发在同一个实例中可复用数据库连接池,减缓下游服务压力。

请求并发密集时,多个请求只需要一个实例进行处理,无需拉起多个实例,从而降低实例冷启动几率,降低响应延迟。

设置为静态并发 50 之后,再来压测试一试

h
[root@VM-12-5-centos /]# ab -n 2000 -c 200 https://service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com/api/options
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com (be patient)
Completed 200 requests
Completed 400 requests
Completed 600 requests
Completed 800 requests
Completed 1000 requests
Completed 1200 requests
Completed 1400 requests
Completed 1600 requests
Completed 1800 requests
Completed 2000 requests
Finished 2000 requests
Server Software:        
Server Hostname:        service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128
Document Path:          /api/options
Document Length:        102 bytes
Concurrency Level:      200
Time taken for tests:   9.619 seconds
Complete requests:      2000
Failed requests:        0
Write errors:           0
Total transferred:      2076000 bytes
HTML transferred:       204000 bytes
Requests per second:    207.93 [#/sec] (mean)
Time per request:       961.884 [ms] (mean)
Time per request:       4.809 [ms] (mean, across all concurrent requests)
Transfer rate:          210.77 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       15   26  27.9     17     116
Processing:    18  568 1569.1    117    9427
Waiting:       18  567 1569.1    117    9427
Total:         34  594 1592.0    135    9538
Percentage of the requests served within a certain time (ms)
  50%    135
  66%    162
  75%    189
  80%    205
  90%    325
  95%   6101
  98%   6368
  99%   6437
 100%   9538 (longest request)

这次没有 Failed requests

而且 90% 的请求在 400 毫秒内就完成了,QPS 达到了 207 / 秒,比在 A 服务器部署的服务快了 1 倍左右

# 性价比评测

同样是 200 个并发 2000 个请求,A 服务器普遍响应比较慢,CPU 占用率达到 70% 左右,如果再多一点并发则服务器可能宕机

云函数通过参数调试与测试之后也完成了 200 并发 2000 请求的测试,成绩比 A 服务器更好,而且不用考虑 CPU 占用率问题,只需考虑并发配额

这里云函数并发配额是最少的情况,每月仅需要 9.9 元,而 1 核 2G1MB 的云服务器一个月费用则为 121

如果项目较为复杂并且占用 CPU 更多的情况,无疑采用 Serverless 部署更为经济

如果每天的用户很多,那么把数据库放在云服务器上,省去购买 RDS 的费用,则每月只需要 100 多元则可以达到以前 4 核乃至 8 核服务器才能承载的并发压力,我认为这就是采用 Serverless 的价值所在!

请我喝杯[咖啡]~( ̄▽ ̄)~*

一个放羊娃 微信支付

微信支付

一个放羊娃 支付宝

支付宝