原文地址: 梁桂釗的博客博客地址:http://blog.720ui.comshell
歡迎關注公衆號:「服務端思惟」。一羣同頻者,一塊兒成長,一塊兒精進,打破認知的侷限性。segmentfault
近期肆虐的新型冠狀病毒,已然成爲大衆視野的焦點。筆者,最近趁過年之際也看了一些相關新聞和書籍,其中,有一本名爲卡爾·齊默《病毒星球》讓我印象深入。固然,本文並非談及新型冠狀病毒和《病毒星球》,而是將故障和病毒進行類比,聊一聊計算機軟件的故障應對機制,而其中關於病毒相關科普性的資料和數據來自於《病毒星球》一書。後端
人鼻病毒做爲普通感冒和哮喘的罪魁禍首,是人類普遍存在的老朋友。鼻病毒巧妙地利用鼻涕來自我擴散。人擤鼻涕的時候,病毒會藉機跑到手上,經過手再蹭到門把手和其餘手碰過的地方。下次其餘人碰到這些地方,病毒就會藉機沾上他們的手,再進入他們的身體——大多數時候也是借道鼻子。鼻病毒能巧妙地讓細胞對它們打開一扇「小門」,繼而入侵位於鼻腔內部、咽喉內部或肺臟內部的細胞。在接下來的幾個小時裏,鼻病毒利用宿主細胞,複製本身的遺傳物質和包裹它們的蛋白外殼。隨後這些複製產生的病毒會從宿主細胞內破壁而出。此外,咱們每一個人的基因組中攜帶了近 10 萬個內源性逆轉錄病毒的 DNA 片斷,佔到人類 DNA 總量的 8%。雖然這類病毒 DNA 中的大多數都沒用,但咱們的祖先也的確「徵用」了一些對咱們自身有好處的病毒。若是沒有這些病毒,咱們甚至無法出生。在演化史上最近的瞬間,人類脫穎而出,病毒對咱們的生存功不可沒。本來就並無什麼「它們」和「咱們」之分——生物在本質上只是一堆不斷混合、不斷閃轉騰挪的 DNA 而已。所以,鼻病毒在幾千年前就開始讓古埃及人患上感冒,內源性逆轉錄病毒早在數千萬年前就入侵了咱們靈長類祖先的基因組。(摘自《病毒星球》)微信
故障也與之相似,它就好似生命體的 DNA 片斷纏繞於計算機軟件中,沒法割捨。現在軟件開發迭代頻繁,咱們很難所有排除故障,只能說盡量多地發現和解決問題,避免故障發生在生產環境致使線上問題。當咱們遭到病毒感染,細胞釋放一種名爲「細胞因子」的信號分子,把附近的免疫細胞都召喚過來。它們讓咱們的身體產生炎性反應,等免疫系統幫咱們把體內的病毒所有幹掉。而在計算機軟件,咱們也會有相似的場景,咱們的開發人員或測試人員一旦確認是程序 BUG,就會當即記錄並周知相關人員進行處理與修復,並持續跟蹤,直至故障解決。網絡
感冒這麼難治,一個緣由是它存在形態多種多樣,因爲其基於突變及快速複製帶來來遺傳多樣性。而面對故障,雖然它的底層導火索可能就只有哪幾種,可是因爲技術的複雜性和業務的複雜性致使了計算機軟件的總體複雜性。app
咱們知道 NPE (NullPointerExcepion)會給咱們帶來巨大災難,可是咱們在實際的研發中常常遺忘或忽視。這裏,因爲沒有對受檢對象進行非空判斷致使 NPE 故障。測試
public static void npe03(){ Person person = null; System.out.println(person.blog); }
下面的示例將會致使 NPE,你發現了嗎?ui
public static void npe01(){ Integer x = 1; Integer y = 2; Integer z = null; Integer val = false ? x * y : z; }
而這個示例,也是很是典型的由 Java 自動裝箱和拆箱致使的 NPE 故障。spa
public static void invoke(){ Long x = null; npe02(x); } public static void npe02(long x){ System.out.println(x); }
再聊一個有意思的故障問題。你們都知道因爲死循環會致使 CPU 100%。可是,致使 CPU 100% 導因是多樣性的,筆者團隊曾經遇到一個 JDK 8 的 BUG,它是因爲 ConcurrentHashMap 遞歸建立對象擴展致使死循環,文章連接:https://mp.weixin.qq.com/s/O6UmB7YDKIYtNvqCOjNwDQ。日誌
一般狀況下,線上故障一旦發生,其後果通常都比較嚴重。因此,咱們須要儘快解決,下降其帶來的影響和資損。例如,咱們團隊以前口號是:「1-5-10」,即一分鐘發現,五分鐘處理,十分鐘解決。那麼,如何作到快速的發現線上故障呢?搭建成熟的監控系統就很是重要啦,例如經過 Zabbix 或 Prometheus 監控各類基礎設施(MySQL、Redis、MongoDB、ElasticSearch 等)運行狀況,以及業務系統的運行狀況,以及 CPU、內存、磁盤 I/O、網絡 I/O 等波動狀況,還有 GC 狀況、binlog 同步狀況等等。那麼,發現問題後,就須要經過告警系統根據業務規則進行多渠道(郵件、釘釘、電話)聯繫故障處理人。要快速解決,怎麼辦?首先,須要一套完備的日誌排查系統(日誌聚合 + 鏈路追蹤),此外,還須要對於 JVM 相關能快速 dump 堆棧信息,對於自助分析有 DevOps 平臺支撐。可是,最主要的仍是須要有一套預案體系。什麼是預案系統?就是針對不一樣的問題,有一套完整的預先方案來快速響應。例如,某個服務不可用了,筆者排查發現是因爲進程假死了,那麼就能夠經過預案裏面的執行方案執行 shell 腳本進行快速拉活。再好比,筆者經過監控告警感知到某個商家資金異常波動,那麼此時經過預案裏面的執行方案將其經過動態開關將其快速熔斷。
可是,若是此次線上故障沒有應急預案,又比較棘手,怎麼辦?別無他法,只能因着頭皮來處理啦。注意的是,故障的評級通常根據業務的影響範圍面而定,事實上,最本質的資金損失,包括直接的資損,例如前段時間某知名電商的免額優惠劵致使很是嚴重的資損;間接的資損,例如挖斷電纜致使整個 app 沒法使用,那麼,轉化成正常的交易額也是大把大把的資損呀。而後呢,過了 2 個小時,故障還沒修復,可能原先定級 P2 的故障就會升級到 P1。
若是發生最差的狀況,就是可能短期內沒法解決,那麼就極可能須要停服維修了。例如,近期肆虐的新型冠狀病毒致使全國性的封城封路,事實上,也是由於咱們沒有特效藥(計算機軟件領域的預案),也尚未研製出新葯(計算機軟件領域的解決方案),因此只能封城封路(計算機軟件領域的停服)。
一般狀況下,偶爾感冒會提供咱們的免疫力。而在計算機領域,偶然採起故障演練也能夠儘量確保在線上運行的系統沒有缺陷和故障。這裏,Netflix 爲應對不肯定性的領域帶來了一種全新的思惟模式:混沌工程。事實上,混沌工程提倡咱們正面接受系統必定會存在缺陷和故障,而後咱們經過一系列實驗找出可能發生問題的風險點,進而不斷地加固系統。
故障演練能夠模擬 CPU 滿載、殺掉指定進程、域名訪問不通、網絡延遲、網絡丟包、填充磁盤、磁盤 IO 高等場景,以下所示。
總結一下,故障就像潛伏於計算機軟件的病毒,因爲技術的複雜性和業務的複雜性致使了其排查和解決的困難性,咱們能夠採起監控、告警、預案,以及故障演練提前發現故障並解決故障。
最後,歡迎關注個人微信公衆號「服務端思惟」,裏面有更多精彩文章與技術乾貨。回覆」669「獲取獨家整理的精選資料集,回覆」加羣「加入全國服務端高端社羣「後端圈」,內容過於專業,僅限服務端從業人員。