这篇是API网关Kong学习笔记(十):Kong在生产环境中的部署与性能测试方法的延续,测试环境中的虚拟机换成了物理机,前半部分沿用之前的测试方法,后面的高并发压测使用效率更高的wrk。
kong0.14.3,envoy 1.8.0
访问端:192.168.128.14 32C64G
服务端:192.168.143.241 24C64G
带宽: 1G
UpStream:位于服务端的容器,Go写的Web服务
envoy的配置见Envoy(一):新型L3~L7层访问代理软件Envoy的使用
UpStream: 4C1G容器
Nginx: 20C
Kong: 20C
Envoy: 无设置,默认all
压测命令:
siege -c 16 -b -t 1M -H "Host: webshell.com" 172.16.129.3/ping
siege -c 16 -b -t 1M -H "Host: webshell.com" 192.168.143.241:7000/ping
siege -c 16 -b -t 1M -H "Host: webshell.com" 192.168.143.241:8000/ping
siege -c 16 -b -t 1M -H "Host: webshell.com" 192.168.143.241:9000/ping
envoy关闭了request id和动态统计,只进行代理与nginx、kong的功能保持一致。
测试结果如下,数据单位是k:
并发 1 16 32 64
--------------------------------------------------------------------------------------------
pod 3.167,3.108,3.252 36.875,36.275,36.290 32.620,34.888,31.775 30.475
nginx 2.454,2.505,2.435 42.112,42.242,42.938 36.031,36.020,37.292 37.416
kong 2.094,2.094,2.067 32.576,32.286,32.879 37.381,36.959,36.307 34.285
envoy 2.228,2.228,2.244 37.433,36.836,36.467 36.356,35.037,38.621 35.779
16并发时,upstream的cpu使用率分别是:400%,397%,320%,380%,说明nginx和envoy代理效率更高。
32并发时,upstream的cpu使用率分别是:400%,400%,400%,400%,说明用于代理的资源充分时,最终能达到相似的吞吐。
32并发时,upstream的cpu使用率均为400%,此时nginx、kong、envoy的CPU使用率分别是339%,730%,500%。
Nginx和Kong使用的是多进程模式,cpu使用率采用的是多个进程的cpu使用率的累加值,cpu使用率十位和个位数字浮动较大,百位基本稳定,其中envoy的使用率是440%~520%,变化较为频发。
(By the way,envoy采用的多线程模式,是否存在一定风险?)
如果网关的机器配置与upstream的机器配置相同时,kong和envoy可能会成为性能瓶颈。
注意:这里所说的瓶颈是针对测试时使用的upstream,测试中使用的upsteam收到请求后直接返回“ok”,并且是低并发、长连接,单核tps是非常高的,9k/cpu,实际业务的tps一定是远远低于这个数值的。
假设网关(可能是多台机器)总共有32核,在仅做代理
的情况下,nginx、kong、envoy的tps上限预计分别是:338k,157k,250k。
nginx: 36k * (32/3.4) = 338.8k
kong: 36k * (32/7.3) = 157.8k
envoy: 36k * (32/5.0) = 230.4k
只要所有upstream的tps上限值累加起来的数值,低于网关的上限,就是安全的。
可以通过估计upstreams的tps上限和统计实际的tps,确定网关需要的资源,例如:
假设业务服务的单核tps上限平均为1.5k(只返回ok的服务的1/6),kubernetes集群共有2000cpu,那么理论上限就是3000k,网关分别需要284cpu,611cpu,417cpu。
而如果业务服务的cpu使用率平均为30%,网关需要的资源可以缩减为:94cpu,203cpu,139cpu,分别是集群cpu总数的5%,10%, 7%。
这种估算方法用到两个关键数值:
1. 业务服务单核tps上限的平均值
2. 业务服务的cpu使用率
这两个数值需要根据实际情况确定,上面用到1.5k和30%,纯粹是假设。
如果开启了envoy的动态统计功能,在32并发、upsteram饱和的情况下,envoy的cpu使用率从500%升高到520%,32cpu的tps理论上限回落到221k,资源需求由139cpu升高到144cpu。
随着网关上植入的功能增加,处理每个请求时执行的cpu指令增加,网关需要的资源和需要增加。
后续会在开启更多网关功能,以及高并发的情况下进一步测试。
测试环境配置:
Upstream: 10C10G
Nginx & Kong: 10 worker,64000 keep alive
Envoy: 10 thread
设置内核参数:
net.ipv4.ip_local_port_range = 1000 65535
测试方法:
siege -c 32 -b -t 1M -H "Host: webshell.com" 172.16.129.4/ping
siege -c 32 -b -t 1M -H "Host: webshell.com" 192.168.143.241:7000/ping
siege -c 32 -b -t 1M -H "Host: webshell.com" 192.168.143.241:8000/ping
siege -c 32 -b -t 1M -H "Host: webshell.com" 192.168.143.241:9000/ping
用siege直接压测pod,使用1000、10000并发时,upstream打不满,发现请求端创建了与并发数相同的进程,可能是进程数量太多导致请求端发送请求的能力受损。 32并发时请求端发送请求的速率最快,对应请求端的32个核,upstream的cpu使用率能够达到800%。
根据之前在虚拟机上压测经验,并发数是upstream的cpu数量的8倍时,整体吞吐最高。 在物理机上将并发数提高到8倍,即80并发时,直连、nginx和kong的压测结果都下降,确信是请求端发送能力不够的原因,因为80并发时upstream的cpu使用率低于32并发时。 另外80并发时,直连、nginx和envoy得到的数据接近,而kong略有提升,也可以佐证这一点:直连、nginx和envoy的测试结果上不去,是因为请求端先到极限了,kong还能略有提升是因为kong的效率比请求端低。
测试结果如下,数据单位是k:
并发 32 64 80
----------------------------------------------------------------------------------
pod 71.174,71.362,71.268 61.988,64.439,60.635 58.345,57.745,60.378
nginx 66.504,64.445,67.751 60.923,61.298,59.322 53.374,56.358,58.558
kong 41.143,43.747,41.393 49.480,51.504,50.108 47.624,48.064,48.633
envoy 53.650,55.477,53.832 55.778,56.804,57.438 50.967,51.698,50.280
可以看到随着并发上升,pod、nginx、envoy的测试结果反而开始下降了,这是压测工具性能不够造成的。
换用效率非常高的wrk压测(wrk效率非常非常,可以用10~20%的cpu将目标机器上的多个cpu打满, siege则几乎是一个cpu只能打满对方一个cpu):
git clone https://github.com/wg/wrk.git
cd wrk
make
wrk使用方法如下:
./wrk -t 32 -c 64 -d 60s -H "Host: webshell.com" http://172.16.129.4/ping
先确定一下怎样为wrk设置线程数/连接数,压测性能更高。
用wrk直接压测upstream,32线程64并发时可以将upstream打满,cpu使用1000%。测试结果如下,数据单位是k:
并发 (线程数/连接数)
32/32 32/64 64/64
----------------------------------------------------------------------------------
pod 90.019,89.613,89.636 96.371,96.422,96.430 96.004,95.661,96.009
可以看到32/64的数据比64/64的数据略高,因此后面的压测全部使用32线程,最终压测使用的命令如下:
./wrk -t 32 -c 64 -d 60s -H "Host: webshell.com" http://172.16.129.4/ping
./wrk -t 32 -c 64 -d 60s -H "Host: webshell.com" http://192.168.143.241:7000/ping
./wrk -t 32 -c 64 -d 60s -H "Host: webshell.com" http://192.168.143.241:8000/ping
./wrk -t 32 -c 64 -d 60s -H "Host: webshell.com" http://192.168.143.241:9000/ping
测试结果如下,数据单位是k:
并发 (线程数/连接数)
32/64 32/640 32/6400 32/64000
--------------------------------------------------------------------------------------------------------
pod 96.371,96.422,96.430 105.249,105.550,105.115 99.091, 99.999, 99.480 76.787
nginx 87.901,86.598,85.300 101.160, 95.653, 93.503 91.020, 88.109, 85.642 89.759
kong 54.841,57.519,57.054 57.150, 57.913, 58.023 54.393, 54.639, 54.581 53.568
envoy 74.506,70.040,72.906 84.067, 85.259, 84.015 111.846,107.235, 106.792 163.270
envoy自动控制了与upstream之间的连接数(1000),不会像nginx和kong那样与upsteam建立大量连接,然后在连接数超过upsteam中的设置时频繁断开连接,envoy在连接控制方面比较优秀。
测试过程中为了避免连接断开重连的情况,为nginx和kong设置的keepalive数值是64000,观测发现,nginx、kong与upstream之间的连接最高到2~3万,envoy与upstream的连接一直是1000。
6400和64000并发时,pod、nginx、kong开始出现socket连接错误,envoy在6400并发时没有socket连接错误,但存在非200的响应。 因此640并发的测试结果更能反应nginx、kong、envoy的性能差异,6400并发和64000并发时都开始出现连接错误或者非200的响应,测试结果不能反应性能差异。