服务器性能问题排查-2

最近出现的问题现象,从2月6日开始:

1. api server上的apache进程数每天不定时会有几个暴涨阶段,接近或达到连接数上限。其中早上和下午开盘时间段必涨,其他时段不定。

2. mysql master和 slave db在相应时段连接数也会暴涨, 接近或达到连接数上限。并且在高峰期,php较容易出现出现有连接不上mysql服务器的报警(属于内网连接)

3. 相应时段,监控系统显示对应的redis连接数也会上涨,但未到上限,高峰期最多也就到600多个连接。

具体数据如下图,分别是apache、mysql master和mysql slave db的连接数

 

问题分析和排查过程如下:

1.  一开始查的重点就集中在apache和mysql本身的性能上,是因为apache和mysql连接数过多,导致了同一时间的redis连接数也较多,并且导致api server所在的服务器cpu load较高。所以先统计了一下高峰期的apache请求数,和同样长的时间段内apache请求数,比如10:50-10:54之间和10:30-10:34之间的api请求数,发现前者的请求数是106057,后者是131607, 说明并不是请求量上涨导致的性能瓶颈。

2.  其次查高峰期的sql是否有异常,api 的php打开了sql的记录功能,统计了一下高峰期和非高峰期的具体sql(包括master和slave的),比如09:25:00-09:36:00之间的select请求,以及09:36:00-09:48:00之间的select请求,发现前者是1423290个,后者是1884498个,统计看了一下具体的sql,发现二者之间也没有明显的差异。说明并不是sql请求过多或者是有性能异常的sql导致。

3.  查看了/var/log/message, 从2月6日起出现了大量的此类错误(日志记录时间有13个小时误差):

Feb 16 20:54:46 localhost kernel: TCP: time wait bucket table overflow
Feb 16 20:54:51 localhost kernel: __ratelimit: 6755 callbacks suppressed

这类信息出现的时间基本都处于盘中,但跟高峰期的时间段并不吻合,也就是当http进程和mysql连接数暴涨的时刻,日志里并不一定有上述错误信息出现。这个错误出现非常奇怪,因为我们/etc/sysctl.conf如下,理论上不应该再有大量的TIME_WAIT存在

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_tw_buckets = 20000

另外,日志里还有大量的如下信息,但这些信息在1月份就已经大量存在

Feb 16 20:57:28 localhost kernel: possible SYN flooding on port 80. Sending cookies.
Feb 16 21:26:42 localhost kernel: possible SYN flooding on port 80. Sending cookies.
Feb 16 21:30:10 localhost kernel: possible SYN flooding on port 80. Sending cookies.

出现这类信息第一怀疑是SYN Flood攻击, 但未得到验证,因为尚未在高峰期通过下列命令查看过网络连接状态,如果发现大量的SYN_RECV连接则可证明是攻击。 但如果是攻击的话,无法解释mysql连接数也同时暴涨的现象。

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 

 所以上述日志中的错误,我们必须要在高峰期实时统计一次连接数才能确定。

 剩下还能想到的可能性,就只能是mysql性能达到瓶颈,在某些时段,同样的sql响应速度要明显降低,从而拖累apache的响应速度。

 下一步要做的事情:

1. 高峰期netstat看一下连接数状态,看看是否被攻击。

2. 高峰期统计一下update和insert 的sql语句,看看有无异常。

3. 加入新的web server,加入nginx负载均衡, 启用新的mysql slave db

4. 新版app发布,行情请求切到新行情服务上,减少apache的请求

5. 完成price_1m/price_5m/price_1h拆表

 

补充:高峰期netstat看了一下连接数,应属正常,SYN_RECV数量并不多,最多的仍然是TIME_WAIT,大概在1w多-2w多个,超过了tcp_max_tw_buckets的值(20000), 所以日志中出现了"time wait bucket table overflow"。 看上去仍然是高峰期的http请求过多。待后继增加web server

posted @ 2015-02-17 14:34  公孙青阳  阅读(736)  评论(0编辑  收藏  举报