⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 https://www.cnkirito.moe/zuul-test/ 「老徐」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

环境准备

采用三台阿里云服务器作为测试 10.19.52.8 部署网关应用-gateway 10.19.52.9, 10.19.52.10 部署用于测试的业务系统 这里写图片描述这里写图片描述

压测工具准备

选用ab作为压力测试的工具,为了方便起见,直接将ab工具安装在10.19.52.8这台机 测试命令如下:

ab -n 10000 -c 100 http://10.19.52.8:8080/hello/testOK?access_token=e0345712-c30d-4bf8-ae61-8cae1ec38c52

其中-n表示请求数,-c表示并发数,上面一条命令也就意味着,100个用户并发对http://10.19.52.8/hello/testOK累计发送了10000次请求。

服务器,网关配置

由于我们使用的tomcat容器,关于tomcat的一点知识总结如下:

Tomcat的最大并发数是可以配置的,实际运用中,最大并发数与硬件性能和CPU数量都有很大关系的。更好的硬件,更多的处理器都会使Tomcat支持更多的并发。

Tomcat 默认的HTTP实现是采用阻塞式的Socket通信,每个请求都需要创建一个线程处理,当一个进程有500个线程在跑的话,那性能已经是很低很低了。Tomcat默认配置的最大请求数是150,也就是说同时支持150个并发。具体能承载多少并发,需要看硬件的配置,CPU越多性能越高,分配给JVM的内存越多性能也就越高,但也会加重GC的负担。当某个应用拥有 250个以上并发的时候,应考虑应用服务器的集群。操作系统对于进程中的线程数有一定的限制: Windows 每个进程中的线程数不允许超过 2000 Linux 每个进程中的线程数不允许超过 1000 在Java中每开启一个线程需要耗用1MB的JVM内存空间用于作为线程栈之用,此处也应考虑。

所以我们修改配置tomcat的默认配置,如下:

server:
tomcat:
accept-count: 1000
max-threads: 1000
max-connections: 2000

无论是网关应用,还是用于测试的业务系统的tomcat,我们都需要如上配置,否则会引起木桶效应,整个调用流程会受到配置最差的应用的干扰。 zuul内部路由可以理解为使用一个线程池去发送路由请求,所以我们也需要扩大这个线程池的容量,配置如下:

zuul:
host:
max-per-route-connections: 1000
max-total-connections: 1000

监控工具

为了确保上述配置真正起作用,我们使用Java VisualVM这个工具监控这几台服务器上部署的tomcat的线程以及内存使用情况。 启动脚本加上如下参数,之后通过工具连接2099端口即可监控

-Dcom.sun.management.jmxremote.port=2099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.19.52.8

开始测试

  • 测试一

    1.通过访问网关,由网关转发,应用端接口延迟200ms后返回一个字符串,模拟真实接口的业务处理延迟

    2.300个线程并发请求,共计100000 次

    ab -n 100000 -c 300 http://10.19.52.8:8080/hello/testOK?access_token=e0345712-c30d-4bf8-ae61-8cae1ec38c52

Document Path:          /hello/testOK?access_token=e0345712-c30d-4bf8-ae61-8cae1ec38c52
Document Length: 2 bytes

Concurrency Level: 300
Time taken for tests: 151.026 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Total transferred: 42200844 bytes
HTML transferred: 200004 bytes
**Requests per second: 662.14 [#/sec] (mean)**
Time per request: 453.078 [ms] (mean)
Time per request: 1.510 [ms] (mean, across all concurrent requests)
Transfer rate: 272.88 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 5 7.0 2 98
Processing: 206 447 478.7 230 3171
Waiting: 197 445 478.7 227 3165
Total: 206 451 478.8 236 3177

Percentage of the requests served within a certain time (ms)
50% 236
66% 250
75% 273
80% 322
90% 1408
95% 1506
98% 1684
99% 1764
100% 3177 (longest request)

测试二: 1.直接访问应用,应用端接口延迟200ms后返回一个字符串,模拟真实接口的业务处理延迟 2.300个线程并发请求,共计100000 次

ab -n 100000 -c 300 http://10.19.52.9:9091/testOK

Server Hostname:        10.19.52.9
Server Port: 9091

Document Path: /testOK
Document Length: 2 bytes

Concurrency Level: 300
Time taken for tests: 69.003 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Total transferred: 13400000 bytes
HTML transferred: 200000 bytes
**Requests per second: 1449.21 [#/sec] (mean)**
Time per request: 207.009 [ms] (mean)
Time per request: 0.690 [ms] (mean, across all concurrent requests)
Transfer rate: 189.64 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.8 0 10
Processing: 200 206 7.7 202 286
Waiting: 200 205 7.7 202 286
Total: 201 206 7.9 203 295

Percentage of the requests served within a certain time (ms)
50% 203
66% 205
75% 207
80% 209
90% 215
95% 220
98% 229
99% 240
100% 295 (longest request)

经过网关路由之后的性能下降是不可避免的,在测试过程中,查看监控端的线程变化,如下图:

这里写图片描述这里写图片描述

我们的配置的确产生了作用。

我们再来分析一下上面测试结果的一个重要指标:Requests per second,我们的网关经过了鉴权之后,性能仍然可以达到600+每秒的响应,是完全可以接受的,峰值时内存情况,使用top指令,如下所示:这里写图片描述这里写图片描述 ab测试命令也占用了一定的cpu使用率,总应用接近70%的cpu使用率,这估计也是单个tomcat实例的瓶颈了。因为我们的应用服务器会单独部署网关,并且可以在多个服务器上部署多个实例,所以这个结果可以接受。

为了避免单次响应带来的偶然因素,我们重复进行测试一(更改为10000次请求,并发量200),看看Requests per second的变化。

1. 799.45
2. 818.86
3. 838.67
4. 833.90
5. 973.65

总结

有一些其他的数据没有整理到博客中,但是也顺便把结论写一下。

这次的测试有几个注意点:

  1. 是在应用服务器端模拟200ms的延时,因为实际请求不可能不伴随着耗时的业务操作,实际发现对ab的测试影响还是较大的,毕竟线程阻塞着,不延迟时request per second能达到2000,加了200ms延迟之后下降到1000+。
  2. 模拟总请求数和线程数的变化会引起QPS/TPS的抖动,即使是在多核CPU的承受范围之内,也并不是说线程越多,QPS/TPS就越高,因为启动线程的开销,以及线程上下文切换的耗时,开辟线程带来的内存损耗都会影响性能。钱总说单个tomcat实例的并发度理论值200就可以接受了,经过参数调优后的tomcat使用zuul做网关能达到如上的测试结果,完全可以投入生产环境使用了。而tomcat默认的150线程,如果使用200的并发度测试就显然是“不公平的”。
  3. 测试注意点有几个,例如ab部署在了api-gateway本机会影响性能,tomcat参数以及zuul参数应当尽可能放开,不让其默认配置影响测试。

本文还有些遗漏的数据,后续会补上…

666. 彩蛋

如果你对 Zuul 感兴趣,欢迎加入我的知识星球一起交流。

知识星球

文章目录
  1. 1. 环境准备
  2. 2. 压测工具准备
  3. 3. 服务器,网关配置
  4. 4. 监控工具
  5. 5. 开始测试
  6. 6. 总结
  • 666. 彩蛋