一次Debug過程的思考

前一段時間,部門接入了新業務,由於業務量小,架構非常簡單,採用了最簡單的LNMP架構,整個項目是交給一個剛畢業的RD負責的,這是背景。

    上線前半天,服務平穩運行。下午的時候,開始收到大量報警:No host could be connected in the cluster。第一反應:mysql服務器不會掛了吧。打開監控,一切正常,登錄也一切正常,但報警一直沒有間斷,這奇怪了。

    實際上一點都不奇怪。“No host could be connected in the cluster”本身不是mysql的錯誤,所以並不是mysql服務器本身出了問題,問題的原因一定是出在封裝的底層的類庫,爲了描述的更明白一些,我先總結一下這個mysql連接管理類庫的功能。

    爲了保證mysql服務的穩定性,我們的mysql連接類庫實現了一個故障自動切換的功能:維護一個當前的mysql服務器的列表,每次連接時隨機選擇一臺服務器連接(這裏不考慮跨機房的問題,也不考慮選擇的算法。選擇機器的算法可以是隨機的,也可以是輪詢的,這不是關鍵),同時維護一個失敗的服務器列表。如果某一次mysql執行失敗,那麼便把這臺服務器從可用的服務器中摘除,同時放置到失敗的服務器列表中, 在一定時間內(interval,比如2s)這臺mysql便不在被訪問。 需要注意的是,這臺mysql並不是一直在失敗的服務器列表中的,經過一段時間後,便會重新釋放,重新進入可用的服務器列表中。這麼做的主要目的,是在某一臺mysql服務器發生故障時,由於這臺mysql被訪問到的概率變小,不至於出現線上服務的大面積癱瘓,也給線上故障轉移提供更多的時間buffer。

    問題就出在這裏!這個自動切換的功能只適用於mysql cluster,也就是存在多個mysql服務器的情況,如果服務器只有一臺,那麼問題就很嚴重了:如果某一次mysql查詢執行失敗了,那麼這臺mysql會被打入冷宮,在接下來的時間間隔內,便沒有任何可用的mysql服務器了!這樣一來,流量一大,所有的interval間隔內的請求便都失敗了!這也是爲什麼線上會出現大量的“No host could be connected in the cluster”的報警。

    這個問題很典型,很多人不清楚類庫的作用,便信手拈來直接使用,所以出現問題的時候常常也是一頭霧水,不知從何下手。尤其在大公司中,類庫、工具、成熟的解決方案都比較齊全,在使用方便的同時,也隱藏了內部的實現邏輯,往往會造成“使用很熟練,原理一竅不通”的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章