背景
GIT服务器5月6日从花海机房迁移至南沙机房后发现负载很高,用户访问慢。
初步检查什么原因引起系统负载高
登录服务器查看负载情况,发现load很高,IO和内存使用正常,CPU使用率idle为0,其中sys高达80%。CPU主要是ssh进程占用,多的时候有300多个sshd进程,其中某个IP会瞬间建立了100多个连接。
查看zabbix上最近两周的数据,可见load和cpu使用率逐步增加,但是奇怪的是CPU使用率中usr time比较稳定,sys time却逐步增加。
点击图片查看大图
怀疑是GIT使用量增长的原因,检查网卡流量,发现流量没有同步增加,可以简单理解为GIT请求没有同步增加。
点击图片查看大图
sshd进程的CPU使用率为什么这么高
怀疑是否是由于sshd进程多导致大量上下文切换,查看zabbix监控和perf top查看,不是这方面的原因。
使用perf top -e cycles 检查,发现CPU使用占比最高的函数为up_read和down_read。
了解了一下up_read和down_read函数,这两个函数是用于控制读写信号量。读写信号量可允许N个读执行单元同时访问共享资源,而最多只能有一个写执行单元。进程调用down_read获取一个读信号量,调用up_read释放一个读信号量。检查up_read和down_read的调用来源:
执行perf record -a -e cpu-clock -g ,然后执行perf report 查看。
按E展开查看,调用关系及消耗占比如下:
为了更直观的查看,下载perf.data生成火焰图。
点击图片查看大图
可见down_read和up_read分别是xfs_ikock和xfs_iunlock在调用,xfs_ilock和xfs_iunlock则是xfs_file_aio_read在调用,最终是sshd进程在调用。检查磁盘分区格式是xfs格式,和QATE同事了解到git服务器之前是ext3格式,网上查询相关资料,发现xfs相比ext3,在读文件的时候也会加锁,而down_read和up_read正是加解锁的函数xfs_ilock和xfs_iunlock在调用。
相关函数:
详细代码左滑查看
xfs_file_aio_read是在读写
什么文件消耗了这么多CPU
首先怀疑是不是由于通过ssh方式访问GIT的请求太多,大量sshd进程在竞争读写同一个文件?
perf top -a -e xfs:xfs_ilock 继续检查xfs_ilock的调用情况,占比最高的设备号是8:2。
查看8:2对应的分区为/dev/sda2
查看/dev/sda2对应的挂载点为/目录,不是GIT代码放的目录,GIT中的数据是存储在/home目录,排除是在读写GIT中的数据。
继续检查是读写/目录中的什么文件,通过strace跟踪sshd连接的相关调用,发现中途open了/目录中大量的文件,没有发现可疑的文件。找了一台centos7.3,文件系统为xfs的vm进行测试,从另外一台服务器大量发起ssh连接并打开vm里面的同一个文件,同时使用perf和strace观察,也未能重现。多次模拟重现无果,找QATE同事看能否在出现故障的GIT服务器上测试重现,QATE同事反馈了一个关键信息,关了pam配置中关于sshd的几个配置项后,sshd进程的CPU使用率降低到正常水平。于是在测试机本地同样开关同样的配置项,未能重现,于是还是在出现故障的git服务器上测试,strace对比开关那几个参数后的区别。
将pam postlogin相关配置行开启:
[root@gitlabns
~]# cat /etc/pam.d/sshd | grep post





















