linux下504错误的排查

今天网站在高峰期突然很多请求都出现了504错误。504错误一般是因为服务器或者程序执行的时间过长导致的,这表示要么是代码出现了问题,要么是服务器出现了问题。由于只是在高峰期的时候突然出现,初步判断可能服务器压力过大。

既然服务器压力过大,那么就因该找出服务器性能的瓶颈所在,对症下药。

第一个可能的瓶颈在于CPU。如果是CPU的负载过高导致,无法及时的处理请求,就会导致请求超时,出现504。所以我首先去看了一下服务器负载的情况。

linux下服务器查看负载的命令有很多,最常使用的莫过于两个命令了:

1、top
2、cat /proc/loadavg

image.png

image.png

前3个参数:0.28, 0.26,  0.25分别表示1分钟, 5分钟和15分钟的平均系统负载,第四个参数表示当前正在处理进程数/总进程数,最后一个参数表示最后一个被执行的进程的PID。我们一般是看15分钟的平均负载,如果15分钟平均负载高,表示CPU一直在超负荷运转。这个时候就需要考虑去升级设备了。

那么这个数值达到多少的时候算高呢?这就需要去理解一下系统负载的含义,网上有这么一段比较好理解的解释:

首先,假设最简单的情况,你的电脑只有一个CPU,所有的运算都必须由这个CPU来完成。

那么,我们不妨把这个CPU想象成一座大桥,桥上只有一根车道,所有车辆都必须从这根车道上通过。(很显然,这座桥只能单向通行。)

系统负荷为0,意味着大桥上一辆车也没有。

系统负荷为0.5,意味着大桥一半的路段有车。

系统负荷为1.0,意味着大桥的所有路段都有车,也就是说大桥已经"满"了。但是必须注意的是,直到此时大桥还是能顺畅通行的。

系统负荷为1.7,意味着车辆太多了,大桥已经被占满了(100%),后面等着上桥的车辆为桥面车辆的70%。以此类推,系统负荷2.0,意味着等待上桥的车辆与桥面的车辆一样多;系统负荷3.0,意味着等待上桥的车辆是桥面车辆的2倍。总之,当系统负荷大于1,后面的车辆就必须等待了;系统负荷越大,过桥就必须等得越久。

CPU的系统负荷,基本上等同于上面的类比。大桥的通行能力,就是CPU的最大工作量;桥梁上的车辆,就是一个个等待CPU处理的进程(process)。

如果CPU每分钟最多处理100个进程,那么系统负荷0.2,意味着CPU在这1分钟里只处理20个进程;系统负荷1.0,意味着CPU在这1分钟里正好处理100个进程;系统负荷1.7,意味着除了CPU正在处理的100个进程以外,还有70个进程正排队等着CPU处理。

为了电脑顺畅运行,系统负荷最好不要超过1.0,这样就没有进程需要等待了,所有进程都能第一时间得到处理。很显然,1.0是一个关键值,超过这个值,系统就不在最佳状态了,你要动手干预了。

上面形容了一个CPU的情况,那么同理,当你的机器为多核时,你有几个CPU,系统最大可承受负载就为几。比如我的服务器为4核4G,那么当我的系统负载长时间处于4时,我就因该要升级配置了。其实网络上总结的最理想的负载因该是每个CPU0.7左右,所以一台4H4G的机器,系统负载最好维持在2.8左右。高于这个值需要引起注意了。

通过查看系统平均负载,我发现系统的平均负载一直维持在2这个水平左右,这表示CPU的性能还有很多没有被利用。那么问题就应该出现在另一方面了。

第二可能的瓶颈在于系统内存。nginx通过php-fpm管理PHP进程,每开启一个进程都需要消耗一定的资源。那么如果某段时间的请求数过多,将会导致内存耗尽无法再开启新的PHP进程,剩下的请求只能堵塞在nginx处,等待前面的请求处理完成,如果堵塞的请求太多,最终导致有些请求超时返回504.

所以我去看了一下内存使用的监控数据,发现内存的使用率一直在一个比较高的水平。所以我们将系统的性能瓶颈定义在了内存这块。

解决方式无非就是优化程序,加强内存使用管理,减少每个PHP程序的内存消耗,另外就是增加服务器配置,使用负载均衡等手段降低单台服务器的压力。


书山有路勤为径 学海无涯苦作舟