今天雙十一,木有節目!!!靜靜寫個文章吧 :-Dphp
2018 年元旦前夕,公司業務系統流量忽然增長 5~6 倍,然而並沒有相關預演或準備,因而乎系統癱瘓了,錢也再也不進帳了,對於小公司來講,痛並快樂着!html
通過這次撲火搶救,我的總結了一些小經驗,大廠用不上,但對總共就幾我的的小微公司而言可能有些幫助。mysql
PHP 技術棧,然而道理是相通的!沒必要糾結世界上最好的語言是哪一個 :)nginx
並不是有意針對CentOS。不過本科的時候折騰過CentOS、Fedora、openSUSE、Mandriva Linux、Elementary OS、Debian、Ubuntu, Ultimate Edition、紅旗 Linux、Ylmf OS(雨林木風OS,並不是Ghost版啊,哈哈哈。現名StartOS)、Linux Deepin(深度OS,一樣並不是Ghost版!)……各類我能接觸到的 Linux 發行版,最終仍是認爲 Ubuntu 更友好,適合我這樣的小白用戶,畢業後遇到了 Linux Mint,至今已用 5 年+。最開始作 iOS 開發的時候還用的虛擬機(當時個人筆記本 i7+16G+SSD,虛擬機還行),後來同事離職騰出一臺 MBP,用了一年左右吧,再後來就不用了,一方面是再也不從事 iOS 開發,另外一方面是我省吃儉用換了一臺 i7+GTX1070+64G+SSD+4K屏幕的筆記本(第一件事情依然是格盤裝上 Linux Mint)。。。web
啓用 OPcache,鳥哥博客文章 《讓PHP7達到最高性能的幾個Tips》 第一條。redis
日誌建議重點關注兩點:sql
清理數據庫慢查詢數據庫
我的認爲,就通常互聯網小公司而言,系統瓶頸通常先出如今數據庫。可能平時業務量小,硬件資源充足,問題不顯現,估計都不過重視這問題。數據庫鏈接池的問題並非瓶頸,面對大量的慢查詢再多的鏈接池也無論用啊,先把慢查詢處掉就行了,查詢慢甚至鎖表可能只是個索引的問題。。。後端
2018 年元旦前夕,系統流量瞬間猛增 5~6 倍,可近期並沒有廣告推廣投入啊,當時第一反應是遭到攻擊了,但冷靜一想,哪一個閒着沒事盯上個小公司,多大仇啊。查看各類數據推斷這次爲天然流量。緩存
因爲無相關演練和應急預案,系統癱瘓了,公司收入也基本停了,痛並快樂着!
我當時首先建議升級 PHP。將其中一臺服務器升級後發現內存和CPU消耗減半 (注:其實並未真正解決問題)。
接着其它服務器也升級了,可尷尬的是,沒過多就,系統又癱瘓了,並且多了不少錯誤日誌。我司用的PHP框架是 ThinkPHP 3.x,疊加歷史遺留問題,根本不可能平滑升級。因而乎降級回到 5.6 的版本。
回到原點,並且問題沒有解決!!!
因而乎,下一個嘗試是,增長服務器數量、提升數據庫鏈接數上限(阿里雲的數據庫)。然而都加倍了,壓力仍是沒有緩解!沒有緩解!換句話說,關鍵不在此,再加就是花冤枉錢。
接着我拿到了一臺服務器的 SSH 帳戶。
注:我我的負責的工做相對雜亂,從 Android 到 iOS,到 Java web 再到 PHP web……,但卻沒管過公司服務器的維護工做,固然我我的負責的外包項目的話就是從服務器選購、系統環境配置到項目開發、部署、維護……,從 0 到 1 全包了。
我首先啓用Opcache,而後調整了 nginx 和 php-fpm 的一些參數,起到了必定的做用,但並未解決問題。
而後我順手把 PHP 的慢執行日誌 slow log 打開了。因爲系統堵得厲害,一大堆的 log,沒能抓到關鍵,當天無果。
推薦個好用的工具 mosh,關鍵時候不掉線哦
畢竟用戶也是要休息的,慢慢流量下去了,系統恢復正常。不過晚上也沒夢到解決方案 :-D
次日,繼續排查,各類調參無果。中午吃過飯後,媽給我來了個電話,問我是否是在加班。這。。。
掛電話後,我犀利的眼睛注意到了一條不起眼的日誌,順着日誌指示的行數,我翻看了一下代碼,發現該行調用了個 usleep 函數,5 秒鐘,個人天,不必吧,因而乎我直接把它註釋掉,重啓 php-fpm,奇蹟出現了,該臺服務器瞬間暢通!接着排查了全部代碼中出現的 usleep 函數,通通註釋掉,重啓 php-fpm。
系統恢復正常服務,錢也開始進來了。。。
然而故事到了這裏還沒結束!
下午流量又逐漸增長,到傍晚飯點的時候,系統又響應緩慢了,但當時我在外吃飯,沒帶電腦,一時也趕不回去,沒辦法,我只好掏出手機試試了。還好下午有先見之明,準備了個批量重啓服務器 php-fpm 的工具,一重啓它就恢復正常了,過段時間堵了就再重啓,原本是有效的,可流量還在增長,慢慢地就無論用了,不過這時我已經吃完飯回到家。立刻電腦打開,繼續奮戰!
再推薦個小工具 PSSH (Parallel SSH)
最後同事定位到的緣由是,另外一個子系統的數據庫的 session 數據表沒添加索引,致使 session 過時的時批量刪除的時間過長,估計是鎖表了。
主系統還可能出問題的地方我都檢查過了(其實我是不清楚還有個老系統在跑☺),並且 session 的驅動也從 mysql 換到了 redis,沒想到的是拖後腿的是個子系統,一款已上線多年的App (這次流量全是它引來的),把數據庫拖垮了。
session 表添加索引後,系統又恢復正常了。
回顧整個撲火過程,關鍵點有兩個,一是 usleep 函數,二是數據庫索引,啓用 OPcache 是有些做用的,而關閉數據庫觸發器啥的也起到了不小的做用,而增長接口緩存時間的操做其實治標不治本,沒有從根本上解決問題,並且此次連表面上解決問題的做用也沒起到。
這次撲救的突破口在於日誌,一是 php-fpm 的慢執行日誌,二是 mysql 的慢查詢日誌。經過排查致使 php-fpm 進程排長隊的緣由就能順藤摸瓜解決問題。
在服務器資源必定的狀況下,php-fpm 的進程數一樣有限,若是出現進程休眠(例如 usleep )或數據庫鏈接數達上限(慢查詢致使)的話,服務器資源充足的狀況下沒問題,但 php-fpm 的進程一旦排長隊,接下來極可能就是雪崩效應,系統就癱瘓了。
以上是本人的一點經驗總結,可能存在很多錯誤和不足,歡迎各位小夥伴來指正和討論,謝謝!
本人普通 985 工科院校,工商管理類專業,雙學位。創業小公司工做 5 年+,全包工程師,
因離家太遠,近期在尋求珠三角地區的新坑,偏後端方向,求介紹啊(已換坑)!