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

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

既然是基于LNMP架构的应用服务器,反正面试官也没说是Web应用还是API应用,我们就索性假装既要为客户端提供API,同时还提供Web页面。


首先第一件事儿就是通过各种方式查看查看各个服务器当前的负载高不高,方式包括登录云服务器控制台,自己用ssh登录到服务器,甚至有条件自己实现了运维监控手段,总之首先要通过最宏观角度看那个哪个服务器负载最高。比如说数据库服务器的cpu负载非常高,那首先大概率就可以确定是mysql服务器的问题了。


其次是看下出口带宽利用率有多高,是不是因为出口带宽被吃的太满太满了导致的卡顿,别笑,这是真的有可能而且极容易被忽视的一个因素。此时,解决方案除了增加带宽外,考虑将静态文件尤其是图片通过CDN来对外透出。


前面说了,这是一个基于lnmp架构的玩意,前面说了最宏观的监控有时候会有一个比较奇怪的现象,就是机器的负载并不高但特么还是卡,这就日了狗了。


既然是LNMP,我们先排除L的问题。那么开始看N的问题,也就是nginx。nginx本身是基于事件监听的异步非阻塞http服务器,自身出现性能平静的概率实际上很低很低的,尤其是在和php搭配时候,往往是php先达到瓶颈。不过既然是面试,那么这里也要多说一点,包括我前面说“nginx本身是基于事件监听的异步非阻塞http服务器,自身出现性能平静的概率实际上很低很低的,尤其是在和php搭配时候,往往是php先达到瓶颈”这句话也要告诉面试官,这样他就知道你对nginx的认识。nginx这里首先检查一下worker进程数量,建议和cpu和核数一样,然后检查worker_connections,这个数字可以稍微配大一些。这里要值得注意的是需要额外将linux的ulimit调整大一些,这个参数的意思就是进程可打开的最大文件数,nginx的worker_connections如果要调大,首先你得将linux的ulimit调大些。基本上到这里,nginx走默认配置,一般自身不会出现什么导致卡顿的。


然后我们将目光放到PHP这一层,关注PHP就是主要是关注两方面。一个是PHP业务代码本身,另一个是fpm进程管理器。首先你看看你配置了多少个fpm进程管理,主要关注最多有多少fpm进程,你可以用ps -aux | grep fpm来查看当前系统有多少fpm进程在运行,然后和你配置中对比一下,看看fpm进程是不是已经被跑满了。当然了,由于有些人使用的fpm配置就是static的,所以你怎么看都是fpm进程都跑满了。但是,通过这个技术手段你要能确定,是不是由于fpm进程数量不够导致业务处理机能不够导致的卡顿。然后,第二个比较坑的就是代码本身的问题,这个需要排查业务代码,最怂的办法就是通过tick time来处理,你可以在所有控制器的入口和出口出用时间差来判定哪个控制器的哪个方法耗费的时间最多,这个方法虽然俗气,但是真的很有效!当然了,fpm的慢日志自然是撒手锏了,打开慢日志然后通过tail -f好好盯着吧,定位问题很快的。


mysql这里更值得关注了。我建议你们在正式上线前就预先把mysql查询慢日志打开了,然后在排查mysql这一层的时候直接就去看慢日志,哪条语句除了问题一目了然。剩下就是三种套路了:


如果sql语句比较负责,你不会加索引,那你就拆语句,一条复杂语句拆成条简单查询 加索引。这个比较磨练你的sql能。首先你要使用explain对sql语句进行解析,然后加上索引后,再次进行explain,多尝试几次,然后确定自己索引加的好加的妙 既不想拆语句,更不会优化sql索引,那就加redis缓存来解决 所以,我就简单总结一下:

  • 静态资源通过CDN解决
  • 检查服务器带宽是否被吃满了
  • 检查nginx worker进程数量以及每个worker进程允许的最大连接数
  • 检查php fpm进程是否足够应付业务并发量
  • 检查php业务代码中是否有二逼的地方,通过tick time或者fpm慢日志
  • 检查mysql是否有慢日志,然后针对出现问题的sql语句进行三种套路的解决方法
  • 绝招是:增加机器

以上基本上可以命中绝大多数卡顿的原因,当然了还有可能是磁盘IO导致的,不过这种类似的一般都是小概率情况了,不过,你回答的越多越详细,对你面试越有利。