针对打开首页接口的性能问题,前文中确定是Gateway在消耗响应时间,达到了近100毫秒。于是,我们开始定位Gateway上的响应时间消耗。
- 第一阶段,关注应用所在的主机,了解到宿主机有四台
- 第二阶段,查看物理机的CPU模式。尝试通过修改CPU运行模式来优化性能。可仍没解决,TPS没见提升,响应时间依旧很长
进入第三阶段,继续分析其他瓶颈点,如wa cpu、资源均衡使用、网络带宽等问题。性能的分析逻辑里,资源均衡使用易被忽略,但又极为重要。通常都盯计数器给出的数值是否异常,而不考虑资源怎么做相应调配。
这案例系统是用k8s管理资源,所以须关注资源的均衡使用,避免出现有些服务性能差,却和性能好的服务分配同样资源。网络资源在k8s会跨好几层,也要着重关注。
请你多思考资源的均衡使用问题。来一起定位gateway上的响应时间消耗。
1 第三阶段:NFS服务器的wa cpu偏高
根据分析的逻辑,仍先看全局监控数据。查全局监控计数器,得到如下视图:
1[root@lenvo-nfs-server ~]# top2top - 00:12:28 up 32 days, 4:22, 3 users, load average: 9.89, 7.87, 4.713Tasks: 217 total, 1 running, 216 sleeping, 0 stopped, 0 zombie4%Cpu0 : 0.0 us, 4.0 sy, 0.0 ni, 34.8 id, 61.2 wa, 0.0 hi, 0.0 si, 0.0 st5%Cpu1 : 0.0 us, 4.7 sy, 0.0 ni, 27.8 id, 67.6 wa, 0.0 hi, 0.0 si, 0.0 st6%Cpu2 : 0.0 us, 6.1 sy, 0.0 ni, 0.0 id, 93.9 wa, 0.0 hi, 0.0 si, 0.0 st7%Cpu3 : 0.0 us, 7.6 sy, 0.0 ni, 3.4 id, 82.8 wa, 0.0 hi, 6.2 si, 0.0 st8KiB Mem : 3589572 total, 82288 free, 775472 used, 2731812 buff/cache9KiB Swap: 8388604 total, 8036400 free, 352204 used. 2282192 avail Mem
计数器wa的CPU使用率偏高,Cpu2的wa已达90%。
wa cpu指CPU读写时,所产生的IO等待时间占CPU时间的百分比
这么高是因为写操作很多吗?就要关注IO状态,因为IO慢绝对是性能问题。
iostat看IO状态:
1[root@lenvo-nfs-server ~]# iostat -x -d 12Linux 3.10.0-693.el7.x86_64 (lenvo-nfs-server) 2020年12月26日 _x86_64_ (4 CPU)3..................4Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util5sda 0.00 0.00 94.00 39.00 13444.00 19968.00 502.44 108.43 410.80 52.00 1275.59 7.52 100.00678Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util9sda 0.00 18.00 137.00 173.00 17712.00 43056.00 392.05 129.46 601.10 38.80 1046.38 3.74 115.9010..................
IO使用率达100%,说明IO过程实在太慢。
再查Block Size,算一下当前IO到底是随机读写还是顺序读写。虽然大部分操作系统都默认Block Size是4096,但是,本着不出小错的原则,我们还是查一下比较放心。
先确定磁盘格式:
1[root@lenvo-nfs-server ~]# cat /proc/mounts2...................3/dev/sda5 / xfs rw,relatime,attr2,inode64,noquota 0 04...................5[root@lenvo-nfs-server ~]#
XFS格式,继续查看Block Size:
1[root@lenvo-nfs-server ~]# xfs_info /dev/sda52meta-data=/dev/sda5 isize=512 agcount=4, agsize=18991936 blks3 = sectsz=512 attr=2, projid32bit=14 = crc=1 finobt=0 spinodes=05data = bsize=4096 blocks=75967744, imaxpct=256 = sunit=0 swidth=0 blks7naming =version 2 bsize=4096 ascii-ci=0 ftype=18log =internal bsize=4096 blocks=37093, version=29 = sectsz=512 sunit=0 blks, lazy-count=110realtime =none extsz=4096 blocks=0, rtextents=011[root@lenvo-nfs-server ~]#
4096,也可看到读写基本都是顺序,不是随机。
来计算一条数据,确认一下
顺序写的能力
若全是随机写:
但实际写只有173次,所以确实是顺序写。
如果一次写了多个block就显然是顺序写;如果一次只写一个block就显然是随机写。
一次写多少个Block?
$(43056times1024)div173div4096approx 62个$
计算次数哪里为啥使用的43056而不是上面util100%对应的写19968?这里要用字节数来算,不能用使用率来算。
我们得出,一次写62个Block。从这样的数据来看,说明顺序写的能力还是不错的。因为对普通磁盘来说,应用在读写的时候,如果是随机写多,那写的速度就会明显比较慢;如果顺序写多,那么写的速度就可以快起来。
你发现了吗?虽然当前磁盘的顺序写能力不错,但是等待的时间也明显比较多。所以,接下来,我们得查一下是什么程序写的。这里我们用iotop命令查看:
1Total DISK READ : 20.30 M/s | Total DISK WRITE : 24.95 M/s2Actual DISK READ: 20.30 M/s | Actual DISK WRITE: 8.27 M/s3 TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 412180 be/4 root 2.39 M/s 16.01 M/s 0.00 % 35.94 % [nfsd]512176 be/4 root 3.20 M/s 0.00 B/s 0.00 % 32.25 % [nfsd]612179 be/4 root 3.03 M/s 6.43 M/s 0.00 % 32.23 % [nfsd]712177 be/4 root 2.44 M/s 625.49 K/s 0.00 % 31.64 % [nfsd]812178 be/4 root 2.34 M/s 1473.47 K/s 0.00 % 30.43 % [nfsd]912174 be/4 root 2.14 M/s 72.84 K/s 0.00 % 29.90 % [nfsd]1012173 be/4 root 2.91 M/s 121.93 K/s 0.00 % 24.95 % [nfsd]1112175 be/4 root 1894.69 K/s 27.71 K/s 0.00 % 24.94 % [nfsd]12...............
可见,IO都是NFS写过来的。那NFS的流量又从哪来?从下面数据看,这些流量从各个挂载了NFS盘的机器写过来,这是我们一开始部署应用时,考虑统一使用NFS来做IO的思路。因为这个机器挂载了一个大容量磁盘,为保证磁盘够用,就把多个主机挂载了NFS盘。
iftop命令:
1 191Mb 381Mb 572Mb 763Mb 954Mb23172.16.106.119:nfs => 172.16.106.130:multiling-http 1.64Mb 2.04Mb 3.06Mb4 172.16.106.100:apex-mesh 1.43Mb 2.18Mb 3.79Mb6 172.16.106.195:vatp 356Kb 1.27Mb 1.35Mb8 172.16.106.56:815 7.83Kb 4.97Kb 4.81Kb10 172.16.106.79:device 11.0Kb 7.45Kb 7.57Kb12 172.16.100.201:cnrprotocol 2.86Kb 2.87Kb 5.81Kb14 225.4.0.2:59004 2.25Kb 2.40Kb 2.34Kb16 225.4.0.2:59004 2.25Kb 2.40Kb 2.34Kb18 172.16.106.149:986 0b 1.03Kb 976b20
在Total DISK WRITE和Total DISK READ可看到,读写能力才 20M。没办法,既然wa这机器能力不好,就只有放弃统一写的思路。不过,为不让机器IO能力差成为应用瓶颈点,再尝试:
- 把MySQL的数据文件移走
- 把Log移走
接着执行场景,希望结果能好。
可查看TPS和RT曲线后,发现结果没改善。TPS依然很低且动荡大:
令人遗憾,那就不得不来到第四阶段。
2 第四阶段:硬件资源耗尽,但TPS仍然很低
先查全局监控的数据。看所有主机的Overview资源:
可见虚拟机k8s-worker-8的CPU使用率已很高,达95.95%。登录到这台虚拟机看更详细的全局监控数据:
因为CPU不超分了,所以很明显看到,k8s-worker-8中的CPU被耗尽。从进程上看,CPU是被当前正在测试的接口服务消耗的。并且在这台虚拟机上,不止有Portal这一个进程,还有很多其他服务。
那就把Portal服务调度到一个不忙的worker,如移worker-3(6C16G):
得到:
TPS已有所上升,达到300,性能确实变好。但这数据还不如一开始不优化的结果,毕竟一开始还能达到300TPS。接着分析当前瓶颈。
先看主机的性能数据:
worker-8 CPU使用率达90.12%。为何这CPU还如此高?继续top看worker-8性能数据:
process中,排在第一的Gateway服务进程消耗CPU最多。
那就看这进程中的线程是不是都在干活:
上图全绿,即Gateway中线程一直处Runnable态,看来工作线程确实挺忙。而前面的worker-8性能数据中,si cpu已达16%。结合这点,看实时的软中断数据:
可见,网络软中断一直往上跳,说明确实是网络软中断导致si cpu变高。网络软中断的变化是根据证据链找下来的:
看网络带宽多大:
倒是不大。从上述Gateway的工作线程、软中断数据和网络带宽情况来看,Gateway只负责转发,并无业务逻辑,也没啥限制。所以,针对TPS上不去原因,似乎除了网络转发能力较差,也找不到其他解释。
这个思路需要一些背景知识,因为我们通常用网络带宽判断网络是不是够用,但这还不够。在网络中,当小包过多,网络带宽是难以达到线性流量的。所以,这里的网络带宽即便不高,也会导致网络软中断的增加和队列的出现。
理解线性流量:假设一个包是1M,那总带宽是100M的话,需要100个包就行。若一个包只有10bit,那就不可能用完100M的总带宽。
既然如此,那就把Gateway也从worker-8移到worker-2(6C 16G),做这一步是为减少网络软中断的争用。
再看下集群整体性能:
看起来不错,worker-8 CPU 使用率降到 56.65%,同时worker-3 CPU 使用率升到 70.78%。不过网络带宽有几个地方变红了,这后面再分析。至少从这里看到,压力是起来了。
回看压力情况:
TPS已达1000!棒!画个TPS对比图:
至此,打开首页接口的基准场景就能结束,因为我们已优化到比需求还高的程度。只是从技术角度,一个系统优化到最后是会有上限,所以,仍要知道这上限在哪。
3 第五阶段:硬件资源还是要用完
现在压力把worker-3的CPU资源用得最高,用到70.78%。那下面就把这机器的硬件资源用完,这才能判断系统容量的最上限。
要将性能优化分两阶段:
- 把资源用起来
- 把容量调上去
就算不是CPU资源,把其他资源用完也可。
既然这时压力已将worker-3 CPU用到70.78%,就到这应用中看线程把CPU用得咋样:
这里的线程确实都忙起来了。
既然如此,把Tomcat和JDBC连接的最大值都改到80,再看TPS(这只是个尝试,改大即可,没啥道理。后续测试过程,还要根据实际情况调整,就是不能让线程太大,也不能不够用)。
为让压力能直接压到一个节点,我们跳过Ingress,用分段的测法直接把压力发到服务。然后,去Pod设置一个node port把服务代理出来,再修改一下压力脚本。得到:
TPS还是抖动大,接着看全局监控:
有几个主机的带宽都红,而其他资源使用率并没有特别高。分析网络问题,不应只看网络带宽,还要分析其他内容,下面就得分析网络带宽。
到监控工具中看网络的流量,看到确实有一些非被测应用在占用带宽,且占得不小:
再看总体带宽,已用4G多:
为弄清那些与被测系统无关的应用,会对带宽消耗产生影响进而影响TPS,先把影响带宽的应用都删除,如Weave Scope、Monitoring的监控工具等,从列表中看这些应用占不小带宽。
再次测试,发现TPS有所上升,稳定很多:
TPS已上升到1200,可见带宽对TPS还是造成不小影响。
接着,查网络的队列,发现应用所在的服务器(应用的所有的服务器)上面已经出现不小的 Recv_Q。
1Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name Timer2tcp 759 0 10.100.69.229:8085 10.100.140.32:35444 ESTABLISHED 1/java off (0.00/0/0)3tcp 832 0 10.100.69.229:34982 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4871.85/0/0)4tcp 1056 0 10.100.69.229:34766 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4789.93/0/0)5tcp 832 0 10.100.69.229:35014 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4888.23/0/0)6tcp 3408 0 10.100.69.229:34912 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4855.46/0/0)7tcp 3408 0 10.100.69.229:35386 10.96.224.111:3306 ESTABLISHED 1/java keepalive (5019.30/0/0)8tcp 3392 0 10.100.69.229:33878 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4495.01/0/0)9tcp 560 0 10.100.69.229:35048 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4888.23/0/0)10tcp 1664 0 10.100.69.229:34938 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4855.46/0/0)11tcp 759 0 10.100.69.229:8085 10.100.140.32:35500 ESTABLISHED 1/java off (0.00/0/0)12tcp 832 0 10.100.69.229:35114 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4921.00/0/0)13tcp 1056 0 10.100.69.229:34840 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4822.69/0/0)14tcp 1056 0 10.100.69.229:35670 10.96.224.111:3306 ESTABLISHED 1/java keepalive (5117.60/0/0)15tcp 1664 0 10.100.69.229:34630 10.96.224.111:3306 ESTABLISHED 1/java keepalive (4757.16/0/0)
从这看,网络已成下一瓶颈。
如果你想接着调优,还可以从应用代码下手,让应用处理得更快。不过,对于基准测试来说,一个没有走任何缓存的接口,在一个6C16G的单节点虚拟机上能达到这么高的TPS,差不多了。
还要去折腾其他接口,对这接口的优化到这里就结束了。
4 总结
在打开首页这个接口的基准场景中,涉及到了很多方面的内容。从一开始的信息整理,比如访问路径、查看代码逻辑、场景试运行等,都是在为后面的分析做准备。
- st cpu高时,看宿主机的CPU运行模式
- wa cpu高的时候,看cat /proc/interrupts cat /proc/softirqs 找到对应的模块和模块的运行原理,最后找出解决方案
- 为什么要把硬件资源用完?找到系统容量的上限
而当我们看到响应时间高,然后做拆分时间这一步,就是我一直在RESAR性能工程中强调的“分析的起点”。因为在此之前,我们用的都是压力工具上的数据,只是把它们罗列出来就好了,没有任何分析的部分。
对于拆分时间,我们能用的手段有多种,你可以用你喜欢的方式,像日志、APM工具,甚至抓包都是可以的。拆分了时间之后,我们就要分析在某个节点上响应时间高的时候,要怎么做。这时就用到了我一直强调的“全局-定向”监控分析思路。
在每一个阶段,你一定要清楚地定义优化的方向和目标,否则容易迷失方向。特别是对于一些喜欢把鼠标操作得特别快的同学,容易失去焦点,我劝你慢点操作,想清楚下一步再动。
而我们上述整个过程,都依赖于我说的性能分析决策树。从树顶往下,一层层找下去,不慌不乱,不急不燥。只要你想,就能做到。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net