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

来源: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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...