既然是基於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導致的,不過這種類似的一般都是小概率情況了,不過,你回答的越多越詳細,對你面試越有利。
