各位朋友聽我一句勸,寫程式碼提供方法給別人調用時,不管是內部系統調用,還是外部系統調用,還是被動觸發調用(例如MQ消費、回調執行等),一定要加上必要的條件校驗。千萬別信某些同事說的這個條件肯定會傳、肯定有值、肯定不為空等等。這不,臨過年了我就被坑了一波,弄了個生產事故,年終獎基本上是涼了半截。
我決定專注於程式碼本身,而非人,以確保系統高可用性和穩定性。以下是幾個小教訓,或許對你也有幫助。
一、事發經過
我的業務場景是:當業務A發生變化時,會觸發發送MQ訊息,然後應用程式會接收到MQ訊息,處理後將資料寫入Elasticsearch。
(1) 收到一個業務A的異常告警,當時的告警如下:
(2) 咋一看覺得有點奇怪,怎麼會是Redis異常呢?然後自己連了下Redis沒有問題,又看了下Redis集群,一切正常。所以就放過了,以為是偶然出現的網路問題。
接著,在技術問題群組裡,客服報告說部分用戶出現異常狀況,我立即檢查系統,確認偶發性問題的存在。
(4) 於是我習慣性的看了幾個核心部件:
- 網關狀況、核心業務Pod的負載狀況、用戶中心Pod的負載狀況。
- Mysql的情況:記憶體、CPU、慢SQL、死鎖、連線數等。
發現了慢SQL和元資料鎖定時間過長的情況,主要是由於一張大表的全表查詢導致資料量過大,執行速度緩慢,進而導致元資料鎖持續時間過長,進而耗盡資料庫連線數。
SELECT xxx,xxx,xxx,xxx FROM 一张大表
(6) 立刻Kill掉幾個慢會話之後,發現系統仍然沒有完全恢復,為啥呢?現在資料庫已經正常了,怎麼還沒完全恢復?又繼續看了應用程式監控,發現用戶中心的10個Pod裡面有2個Pod異常了,CPU和記憶體都爆了。難怪使用時會出現偶發性的異常呢。於是趕緊重啟Pod,先把應用程式恢復。
(7) 問題找到了,接下來就繼續排查為什麼用戶中心的Pod掛掉了。從以下幾個懷疑點開始分析:
- 同步資料到Elasticsearch的程式碼是不是有問題,怎麼會出現連不上Redis的情況呢?
- 會不會是異常過多,導致發送異常警報訊息的執行緒池佇列滿了,然後就OOM?
- 哪裡會對那張業務A的大錶做不帶條件的全表查詢呢?
(8) 繼續排查懷疑點a,剛開始以為:是拿不到Redis鏈接,導致異常進到了線程池隊列,然後隊列撐爆,導致OOM了。依照這個設想,修改了程式碼,升級,繼續觀察,依舊出現同樣的慢SQL 和 使用者中心被幹爆的狀況。因為沒有異常了,所以懷疑點b也可以被排除了。
(9) 此時基本上可以肯定是懷疑點c了,是哪裡調用了業務A的大表的全表查詢,然後導致用戶中心的內存過大,JVM來不及回收,然後直接乾爆了CPU 。同時也是因為全表資料太大,導致查詢時的元資料鎖時間過長造成了連線不能夠及時釋放,最終幾乎被耗盡。
(10) 於是修改了查詢業務A的大表必要校驗條件,重新部署上線觀察。最終定位出了問題。
二、問題的原因
因為在變更業務B表時,需要發送MQ訊息( 同步業務A表的數據到ES),接受到MQ訊息後,查詢業務A表相關連的數據,然後同步數據到Elasticsearch。
但是變更業務B表時,沒有傳業務A表所需的必要條件,同時我也沒有校驗必要條件,從而導致了對業務A的大表的全表掃描。因為:
某些同事说,“这个条件肯定会传、肯定有值、肯定不为空...”,结果我真信了他!!!
由於業務B表當時變更頻繁,發出和消費的MQ訊息較多,觸發了更多的業務A的大表全表掃描,進而導致了更多的Mysql元數據鎖時間過長,最終連接數消耗過多。
同時每次都是把業務A的大表查詢的結果返回到用戶中心的內存中,從而觸發了JVM垃圾回收,但是又回收不了,最終內存和CPU都被乾爆了。
至於Redis拿不到連線的異常也只是個煙霧彈,因為發送和消費的MQ事件太多,瞬時間有少部分執行緒確實拿不到Redis連線。
最後我在消費MQ事件處的程式碼裡增加了條件校驗,同時也在查詢業務A表處也增加了的必要條件校驗,重新部署上線,問題解決。
三、總結教訓
經過此事,我也總結了一些教訓,與君共勉:
(1) 時時警惕線上問題,一旦出現問題,千萬不能放過,趕緊檢查。不要再去懷疑網路抖動問題,大部分的問題,都跟網路無關。
(2) 業務大表本身要做好保護意識,查詢處一定要增加必須條件校驗。
(3) 消費MQ訊息時,一定要做必要條件校驗,不要相信任何資訊來源。
(4) 千萬別信某些同事說,「這個條件一定會傳、肯定有值、肯定不為空」等等。為了保障系統的高可用和穩定,咱們只認代碼不認人。
(5) 一般出現問題時的排查順序:
- 資料庫的CPU、死鎖、慢SQL。
- 應用的網關和核心部件的CPU、記憶體、日誌。
(6) 業務的可觀測性和警告必不可少,而且必須要全面,這樣才能更快的發現問題和解決問題。
以上是系統乾崩了,只認代碼不認人的詳細內容。更多資訊請關注PHP中文網其他相關文章!

一些Windows 11/10用戶報告說,他們看到BitDefender更新後立即打開CMD窗口,並且正在運行SecurebootencOdeuefi.exe。該帖子來自PHP.CN介紹瞭如何刪除SecurebootencOdeuefi.exe Trojan。

sysdll_win64_retail.dll是與FIFA 17應用程序相關的動態鏈接庫(DLL)文件。當該文件丟失或損壞時,該應用程序將發生一系列問題和錯誤。要解決這個問題,您可以閱讀此含義

許多Surfacebook用戶報告說,他們符合Windows 11/10上的“由EW_USBCCGPFILTER.SYS阻止的核心隔離”問題。 PHP.CN的這篇文章有助於解決煩人的問題。繼續閱讀。

當您在計算機上按CTRL ALT DEL時,您將輸入“安全選項”窗口,其中可能會看到鎖定,切換用戶並登錄選項。您知道這些選項可以更改嗎?此php.cn帖子將向您展示如何刪除OPT

一些Windows 11/10用戶報告說,他們的Windows Defender發現了一種名為病毒的病毒:win32/grenam.va! MSR。但是他們不知道如何刪除它。這篇來自Php.cn的帖子教您如何去除病毒:win32/grenam.va! MSR。

當您需要經常訪問網站時,打開瀏覽器並每次搜索它非常麻煩。您為什麼不嘗試將網站保存為應用?如果這樣做,則可以作為普通軟件打開它。在這裡,php.cn為您提供一些USEFU

當他們安裝最新的Windows更新時,有些人在Windows 11上遇到了錯誤代碼0x00000000。您應該怎麼做才能應對此意外錯誤? PHP.CN網站上的本文將為您提供一些解決問題的線索。

在團隊或Excel打開文件時,您是否會遭受錯誤消息“此應用程序所選擇的FILETYPE”?現在,請閱讀PHP.CN的這篇文章,以獲取有關此問題的一些有用解決方案。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

記事本++7.3.1
好用且免費的程式碼編輯器

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3漢化版
中文版,非常好用