A. 测试条件说明
- 创建服务:创建 asp.net core webapi 项目。
- 服务间接口调用:因为是.NET Core开发平台,服务间调用使用的是 HttpClient。需要验证 HttpClient 的性能瓶颈。
- 服务运行环境:分为独立运行和容器运行(因生产环境中使用了 Docker)。
- 网络环境:分为直连和代理连接(基于 nginx 反向代理)。
- 压力测试工具:wrk
- 测试机:3台 linux 阿里云服务器(同一局域网内)
- hp-spark-test(A):接口服务器(10.51.40.211)
- hp-node-test(B):nginx服务器(10.117.75.102)
- bs-node-test-01(C):压力测试客户端(10.117.197.215)
B. 压力测试时需要关注的指标
- cpu
- 内存
- 带宽
- 其他IO
- Requests/sec
- Transfer/sec
C. 测试场景
1. 独立运行/容器运行
wrk -> A
-
结论:经多次测试,服务两种运行方式(独立运行、容器运行)在性能上几乎没有差异
-
测试结果:
wrk -c 50 -t 2 -d 20 http://10.51.40.211:8001/api/values
Running 20s test @ http://10.51.40.211:8001/api/values
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.64ms 2.44ms 46.23ms 91.63%
Req/Sec 11.25k 1.18k 14.32k 70.75%
447718 requests in 20.00s, 76.00MB read
Requests/sec: 22382.06
Transfer/sec: 3.80MB
wrk -c 50 -t 2 -d 20 http://10.51.40.211:8002/api/values
Running 20s test @ http://10.51.40.211:8002/api/values
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.63ms 2.36ms 44.67ms 91.00%
Req/Sec 11.15k 1.20k 23.01k 80.05%
445152 requests in 20.10s, 75.57MB read
Requests/sec: 22147.72
Transfer/sec: 3.76MB
2. 独立运行/容器运行 + 反向代理
wrk -> nginx -> A
-
结论:
- 2.1. 经多次测试,服务两种运行方式(独立运行、容器运行)在性能上几乎没有差异
- 2.2. 加入反向代理后,最好的情况也只是场景1的1/3(RPS)
- 2.3. 加入反向代理后,测试结果不稳定,最好是7k多(RPS),最差不到10(RPS)
-
分析:
观察nginx服务器和接口服务器的CPU的利用使用情况,发现CPU的利用率与测试结果成正比;也就是CPU利用率低时测试结果就差,测试结果差时CPU利用率低 -
测试结果:
wrk -c 50 -t 2 -d 20 http://10.117.75.102:8001/api/values
Running 20s test @ http://10.117.75.102:8001/api/values
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 11.81ms 55.34ms 1.01s 98.86%
Req/Sec 3.79k 532.76 6.30k 82.00%
150684 requests in 20.00s, 29.60MB read
Requests/sec: 7532.78
Transfer/sec: 1.48MB
wrk -c 50 -t 2 -d 20 http://10.117.75.102:8002/api/values
Running 20s test @ http://10.117.75.102:8002/api/values
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 124.49ms 260.32ms 1.02s 86.81%
Req/Sec 1.00k 1.21k 3.49k 72.60%
7653 requests in 20.03s, 1.50MB read
Socket errors: connect 0, read 0, write 0, timeout 90
Requests/sec: 382.15
Transfer/sec: 76.86KB
3. 独立运行/容器运行 + 2级服务
wrk -> A2 -> A
-
分析:优化前,在压力测试过程中,发现 A2 服务与 A 服务产生大量连接(即使只使用了一个 HttpClient 对象),且性能很差;后来将 HttpClient 的使用从同步改为异步(A2 服务的 Controler 中的 Action 声明为异步方法),性能有了显著提升。
-
结论:API 服务需全部重构,将 Action 方法修改为异步方法。
-
压力测试 A2 服务(优化前)
wrk -c 100 -t 2 -d 20 http://10.51.40.211:8101/api/values
Running 20s test @ http://10.51.40.211:8101/api/values
2 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 0.00us 0.00us 0.00us -nan%
Req/Sec 0.00 0.00 0.00 -nan%
0 requests in 20.03s, 0.00B read
Requests/sec: 0.00
Transfer/sec: 0.00B
- 压力测试 A2 服务(优化后)
wrk -c 100 -t 2 -d 20 http://10.51.40.211:8101/api/values
Running 20s test @ http://10.51.40.211:8101/api/values
2 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 72.98ms 149.66ms 1.07s 93.49%
Req/Sec 1.42k 351.50 2.07k 69.84%
52194 requests in 20.01s, 9.31MB read
Requests/sec: 2608.12
Transfer/sec: 476.30KB
4. 独立运行/容器运行 + 3级服务
wrk -> A3 -> A2 -> A
- 压力测试 A3 服务(优化后)
wrk -c 50 -t 2 -d 20 http://10.51.40.211:8201/api/values
Running 20s test @ http://10.51.40.211:8201/api/values
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 32.63ms 12.58ms 128.48ms 76.19%
Req/Sec 776.58 149.07 1.14k 68.00%
30932 requests in 20.01s, 5.52MB read
Requests/sec: 1545.60
Transfer/sec: 282.25KB
5. 独立运行/容器运行 + 2级服务 + 反向代理
wrk -> A2 -> nginx -> A
wrk -c 50 -t 2 -d 20 http://10.51.40.211:8101/api/values
Running 20s test @ http://10.51.40.211:8101/api/values
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 26.81ms 38.27ms 1.05s 99.29%
Req/Sec 1.02k 159.05 1.38k 68.75%
40515 requests in 20.01s, 6.88MB read
Requests/sec: 2024.54
Transfer/sec: 351.92KB
6. 独立运行/容器运行 + 3级服务 + 反向代理
wrk -> A3 -> nginx -> A2 -> nginx -> A
wrk -c 50 -t 2 -d 20 http://10.51.40.211:8201/api/values
Running 20s test @ http://10.51.40.211:8201/api/values
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 93.94ms 218.56ms 1.51s 94.42%
Req/Sec 579.89 97.77 840.00 75.00%
21489 requests in 20.01s, 3.83MB read
Requests/sec: 1073.76
Transfer/sec: 196.09KB
D. 立运行/容器运行 + 2级服务 + 反向代理 + 数据库连接
问题:因优化后的代码应用到项目中后,在并发100的情况下仍然出现性能问题,后经过排查发现是因为数据库连接与HttpClient调用同时存在时会出现问题,也就是说单独压测数据库连接或者单独压测 HttpClient 都性能OK
解决:后来将数据库连接改为异步方式后,问题解决
E. 结论
根据上述多个场景的测试,发现我们的微服务架构中,对性能影响较大的因素:
- 异步使用 HttpClient,在 Controller 中声明的 Action 需要使用异步方式
- nginx 作为反向代理服务,稳定性的问题
- 数据库连接需要使用异步方式










网友评论