一个基于LNMP架构的应用服务器出现卡顿现象,如何排查原因?

既然是LNMP架构,我们就由L、N、M、P一个个来分析:

首先是Linux,我们可以登陆服务器使用TOP命令看下服务器负载,如果是服务器负载高的话,先观察一下是哪个服务导致的,是不是必须服务,不是的话就直接kill掉。如果是单纯的因为访问量大而导致的负载过高,那就应该考虑一下增加服务器的问题了。如果过负载没有问题的话,可以去观察一下出入口的带宽是不是满了,这个是非常容易忽略的一个点(我在压测一个用Swoole写的TCP服务器时就出现了这个问题,1核2G,1M带宽的小水管一下被挤满了,导致并发怎么也提不上去)。如果是带宽的问题可以考虑增加带宽,或者是将图片,css文件等静态资源放到CDN上去。

如果Linux没有问题的话,再来看看Nginx,其实一般情况下Nginx会出现性能瓶颈的几率是很低的,在搭配PHP时,通常是PHP先出现瓶颈。但也不是说我们就不用考虑Nginx了,如果服务器本身配置很好的话,我们可以去改动一下Nginx的默认配置,使其性能更上一层楼。重点可以看一下woker和woker_connections这两个参数,woker可以设置为CPU核数,woker_connections的值可以设置得大一点(提升woker_connections值时也要记得提升ulimit的值啊),并将gzip等配置开启(用于压缩css,js等静态文件)。

接着就到了PHP了。首先我们可以先看一下PHP配置,看看是不是php-fpm启动少了,根据服务器内存大小判断是不是可以增加fpm进程(我一般按照每个fpm进程占用30M内存来计算)。同时我们也可以看一下opcache,平滑重启等配置是否开启,这能提升部分PHP的性能。如果配置没有问题的话,我们就需要去代码中找问题了,这时可以先开启PHP的慢日志,运气好的话直接通过慢日志就能发现问题出现在哪。如果还不行的话,只能去代码中判断可能出问题的点,记录该段代码的运行时间,看看问题是不是出在这。

然后就到了最容易出先瓶颈的地方了:MySQL数据库。可以首先去MySQL慢日志中查看一下,找到对应的慢查询语句,然后explain分析,根据实际情况判断是否需要加索引或者使用强制索引,或者是将复杂SQL语句改为几条简单的SQL语句,将一些需要计算的数据交由PHP去计算,而不是使用MySQL内置函数。另外可以看一下是不是单表中数据太多,是否需要进行分库分表等操作。最后对于慢查询还有一个绝招,那就是增加缓存(例如我们的项目中有些地方需要使用商户树,几十万的商户数据实时去计算生成树无疑是来不及的,所以我们通过脚本跑出树,然后加入缓存中,半个小时更新一次)。


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