Zuul 性能测试
环境准备
采用三台阿里云服务器作为测试
10.19.52.8 部署网关应用 -gateway
10.19.52.9, 10.19.52.10 部署用于测试的业务系统
压测工具准备
选用 ab 作为压力测试的工具,为了方便起见,直接将 ab 工具安装在 10.19.52.8 这台机
测试命令如下:
1 | 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 的默认配置,如下:
1 | server: |
无论是网关应用,还是用于测试的业务系统的 tomcat,我们都需要如上配置,否则会引起木桶效应,整个调用流程会受到配置最差的应用的干扰。
zuul 内部路由可以理解为使用一个线程池去发送路由请求,所以我们也需要扩大这个线程池的容量,配置如下:
1 | zuul: |
监控工具
为了确保上述配置真正起作用,我们使用 Java VisualVM 这个工具监控这几台服务器上部署的 tomcat 的线程以及内存使用情况。
启动脚本加上如下参数,之后通过工具连接 2099 端口即可监控
1 | -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 |
开始测试
- 测试一
- 通过访问网关,由网关转发,应用端接口延迟 200ms 后返回一个字符串,模拟真实接口的业务处理延迟 2.300 个线程并发请求,共计 100000 次
1
ab -n 100000 -c 300 http://10.19.52.8:8080/hello/testOK?access_token=e0345712-c30d-4bf8-ae61-8cae1ec38c52
1 | Document Path: /hello/testOK?access_token=e0345712-c30d-4bf8-ae61-8cae1ec38c52 |
测试二:
- 直接访问应用,应用端接口延迟 200ms 后返回一个字符串,模拟真实接口的业务处理延迟
- 300 个线程并发请求,共计 100000 次
1 | ab -n 100000 -c 300 http://10.19.52.9:9091/testOK |
1 | Server Hostname: 10.19.52.9 |
经过网关路由之后的性能下降是不可避免的,在测试过程中,查看监控端的线程变化,如下图:
我们的配置的确产生了作用。
我们再来分析一下上面测试结果的一个重要指标:Requests per second,我们的网关经过了鉴权之后,性能仍然可以达到 600+ 每秒的响应,是完全可以接受的,峰值时内存情况,使用 top 指令,如下所示:
ab 测试命令也占用了一定的 cpu 使用率,总应用接近 70% 的 cpu 使用率,这估计也是单个 tomcat 实例的瓶颈了。因为我们的应用服务器会单独部署网关,并且可以在多个服务器上部署多个实例,所以这个结果可以接受。
为了避免单次响应带来的偶然因素,我们重复进行测试一(更改为 10000 次请求,并发量 200),看看 Requests per second 的变化。
1 | 1. 799.45 |
总结
有一些其他的数据没有整理到博客中,但是也顺便把结论写一下。
这次的测试有几个注意点:
- 是在应用服务器端模拟 200ms 的延时,因为实际请求不可能不伴随着耗时的业务操作,实际发现对 ab 的测试影响还是较大的,毕竟线程阻塞着,不延迟时 request per second 能达到 2000,加了 200ms 延迟之后下降到 1000+。
- 模拟总请求数和线程数的变化会引起 QPS/TPS 的抖动,即使是在多核 CPU 的承受范围之内,也并不是说线程越多,QPS/TPS 就越高,因为启动线程的开销,以及线程上下文切换的耗时,开辟线程带来的内存损耗都会影响性能。钱总说单个 tomcat 实例的并发度理论值 200 就可以接受了,经过参数调优后的 tomcat 使用 zuul 做网关能达到如上的测试结果,完全可以投入生产环境使用了。而 tomcat 默认的 150 线程,如果使用 200 的并发度测试就显然是“不公平的”。
- 测试注意点有几个,例如 ab 部署在了 api-gateway 本机会影响性能,tomcat 参数以及 zuul 参数应当尽可能放开,不让其默认配置影响测试。
Zuul 性能测试