系統乾崩了,只認代碼不認人

来源:https://www.cnblogs.com/mangod/p/18007504
-Advertisement-
Play Games

各位朋友聽我一句勸,寫代碼提供方法給別人調用時,不管是內部系統調用,還是外部系統調用,還是被動觸發調用(比如MQ消費、回調執行等),一定要加上必要的條件校驗。千萬別信某些同事說的這個條件肯定會傳、肯定有值、肯定不為空等等。這不,臨過年了我就被坑了一波,弄了個生產事故,年終獎基本是涼了半截。 為了保障 ...


各位朋友聽我一句勸,寫代碼提供方法給別人調用時,不管是內部系統調用,還是外部系統調用,還是被動觸發調用(比如MQ消費、回調執行等),一定要加上必要的條件校驗。千萬別信某些同事說的這個條件肯定會傳、肯定有值、肯定不為空等等。這不,臨過年了我就被坑了一波,弄了個生產事故,年終獎基本是涼了半截。

為了保障系統的高可用和穩定,我發誓以後只認代碼不認人。文末總結了幾個小教訓,希望對你有幫助。

一、事發經過

我的業務場景是:業務A有改動時,發送MQ,然後應用自身接受到MQ後,再組合一些數據寫入到Elasticsearch。以下是事發經過:

  1. 收到一個業務A的異常告警,當時的告警如下:

  2. 咋一看覺得有點奇怪,怎麼會是Redis異常呢?然後自己連了下Redis沒有問題,又看了下Redis集群,一切正常。所以就放過了,以為是偶然出現的網路問題。

  3. 然後技術問題群里 客服 反饋有部分用戶使用異常,我警覺性的感覺到是系統出問題了。趕緊打開了系統,確實有偶發性的問題。

  4. 於是我習慣性的看了幾個核心部件:

    1. 網關情況、核心業務Pod的負載情況、用戶中心Pod的負載情況。
    2. Mysql的情況:記憶體、CPU、慢SQL、死鎖、連接數等。
  5. 果然發現了慢SQL和元數據鎖時間過長的情況。找到了一張大表的全表查詢,數據太大,執行太慢,從而導致元數據鎖持續時間太長,最終資料庫連接數快被耗盡。

SELECT xxx,xxx,xxx,xxx FROM 一張大表
  1. 立馬Kill掉幾個慢會話之後,發現系統仍然沒有完全恢復,為啥呢?現在資料庫已經正常了,怎麼還沒完全恢復呢?又繼續看了應用監控,發現用戶中心的10個Pod里有2個Pod異常了,CPU和記憶體都爆了。難怪使用時出現偶發性的異常呢。於是趕緊重啟Pod,先把應用恢復。
  2. 問題找到了,接下來就繼續排查為什麼用戶中心的Pod掛掉了。從以下幾個懷疑點開始分析:
    1. 同步數據到Elasticsearch的代碼是不是有問題,怎麼會出現連不上Redis的情況呢?
    2. 會不會是異常過多,導致發送異常告警消息的線程池隊列滿了,然後就OOM?
    3. 哪裡會對那張業務A的大表做不帶條件的全表查詢呢?
  3. 繼續排查懷疑點a,剛開始以為:是拿不到Redis鏈接,導致異常進到了線程池隊列,然後隊列撐爆,導致OOM了。按照這個設想,修改了代碼,升級,繼續觀察,依舊出現同樣的慢SQL 和 用戶中心被乾爆的情況。因為沒有異常了,所以懷疑點b也可以被排除了。
  4. 此時基本可以肯定是懷疑點c了,是哪裡調用了業務A的大表的全表查詢,然後導致用戶中心的記憶體過大,JVM來不及回收,然後直接乾爆了CPU。同時也是因為全表數據太大,導致查詢時的元數據鎖時間過長造成了連接不能夠及時釋放,最終幾乎被耗盡。
  5. 於是修改了查詢業務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. 一般出現問題時的排查順序:
    1. 資料庫的CPU、死鎖、慢SQL。
    2. 應用的網關和核心部件的CPU、記憶體、日誌。
  6. 業務的可觀測性和告警必不可少,而且必須要全面,這樣才能更快的發現問題和解決問題。

======>>>>>> 關於我 <<<<<<======

本篇完結!歡迎點贊 關註 收藏!!!

原文鏈接https://mp.weixin.qq.com/s/TvIpTZq0XO8v9ccYSsM37Q


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ZooKeeperServer 實現了單機版zookeeper服務端功能,子類實現了更加豐富的分散式集群功能: ZooKeeperServer |-- QuorumZooKeeperServer |-- LeaderZooKeeperServer |-- LearnerZooKeeperServer ...
  • 臨時接到一個需求說讓根據按照下麵的這個圖片的結構來打包下載指定位置下的文件到指定位置! 實現思路: 1.把已經實現的樹形結構的代碼進行調用,拿到他的數據進行創建對應的文件夾 2.因為結構下方的文件沒有特別直觀的資料庫中的關聯關係,所以還需要對於管理關係進行梳理 3.創建好階級文件,然後調用網上找的工 ...
  • 在該文章中,我們基於OpenVINO™ Python API 向大家展示了包含後處理的RT-DETR模型的部署流程,但在實際工業應用中,我們為了與當前軟體平臺集成更多會採用C++平臺,因此在本文中,我們將基於OpenVINO™ C++ API 向大家展示了不包含後處理的RT-DETR模型的部署流程,... ...
  • 目錄1. 引言2. 優化過程2.1. 進程對象定義與初步分析2.2. 排除Json序列化2.3. 使用BinaryWriter進行二進位序列化2.4. 數據類型調整2.5. 再次數據類型調整與位域優化3. 優化效果與總結 1. 引言 在操作系統中,進程信息對於系統監控和性能分析至關重要。假設我們需要 ...
  • C# Switch 語句 使用 switch 語句選擇要執行的多個代碼塊中的一個。 示例: switch(expression) { case x: // 代碼塊 break; case y: // 代碼塊 break; default: // 代碼塊 break; } 它的工作方式如下: 評估 s ...
  • 背景:今天接到客戶一個需求,就是在收銀員在用掃碼槍掃顧客會員碼或者微信付款碼的時候判斷用戶有沒有加企微好友和進企微群,然後根據這個狀態進行語音播報,判斷顧客能不能享受優惠價。關鍵難點就是用戶用的收銀系統是別家的,線上小程式用的是我們家的,兩家不互通,所以立即決定採用Hook鉤子技術做一工具掛在其他收 ...
  • 使用C#中的Dictionary與ConcurrentDictionary進行多線程操作 在C#中,Dictionary是一個常見的字典類型,但它不是線程安全的。為了在多線程環境中確保全全的操作,我們可以使用ConcurrentDictionary,這是一個專門設計用於多線程場景的線程安全字典。 1 ...
  • 在 .NET 中,Task 和 ValueTask 都是用於表示非同步操作的類型,但它們有一些重要的區別。 Task Task 是最常見的表示非同步操作的類型。它通常用於表示耗時的、非同步的操作,比如從文件讀取數據、執行資料庫查詢等。Task 是一個引用類型,它封裝了非同步操作的狀態和結果。 using S ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...