對話:一個工程師在蘑菇街4年的架構感悟

一杯甜酒發表於2016-05-04
蘇武,蘑菇街工程師,2012 年加入蘑菇街,經歷過數年蘑菇街系統的改造升級。曾負責 2014、2015 年雙十一穩定性保障工作,目前主要負責全站穩定性工作。高可用架構:作為架構師,在蘑菇街的技術演進過程中,最難忘的成長經歷或挑戰是什麼?蘇武:挑戰和問題時時刻刻都有,如果說對個人成長最重要的,我覺得有以下兩次:第一次是 2014 年,整個蘑菇街從一個機房一夜之間搬遷到了另外一個機房,這兩個機房還不在同一個省份,我主導了這個專案;第二次,2015 年的雙 11,我主導了系統保障工作。先談下第一個專案:蘑菇街機房遷移我加入蘑菇街之前,一直在做業務系統開發,加入蘑菇街後做的事情就比較雜,之前我對 Java 這一塊很熟悉,但運維和基礎架構也只是聽說過而已。2014 年接到機房遷移這個專案,不得不推著我去了解蘑菇街總體的情況,包括機房、整體架構、系統運維、後端儲存、DB、cache、中間系統之前的依賴和前面接入方式等。這個專案前後準備了 3 ~ 4 個月,演練了不下 10 次。通過這個專案,我基本摸清了整個蘑菇街的架構情況。在這個專案的收穫主要有:知識範圍變廣了,有機會去了解和思考所有的技術方案與決策。比如在遷移的過程中,曾經出現過開源系統出問題不可服務的情況,在當時這些問題超出了我們當時能夠處理的範圍。通過這個專案,使得我們重新審視對開源系統的評估和使用。有機會重新來審視當前的架構,看到了很多做得好和不好的地方。做得好的加以吸收,不好的後面加以改進,我個人後續也參與了部分改進專案。相當於上了一堂架構平衡藝術的課。架構沒有完美,只求在時間、資源、需求三者之間有比較好的平衡。提升了溝通能力。在溝通這一塊,和大多數技術人員一樣,我不太習慣和陌生人打交道,會有一定焦慮的心理。但在大型專案中溝通的事情是免不了,經歷了這個專案也讓我多了溝通的信心。第二個專案是 2015 年雙 11 的系統保障工作雖然準備了每秒幾千單的峰值容量,但由於在 2014 年雙 11 和 2015 年的 321 峰值時,系統都有出現過一些可用性問題,所以 2015 年雙 11 對技術團隊的壓力是很大的。當時在保障的思路上面我們也做了一系列改變。比如 321 之後馬上開始服務化的改造,把 PHP 遷移到 Java 上;在 9 月份的時候就開始針對雙十一做架構風險梳理,通過業務目標評估系統峰值,主鏈路上做限流和降級的改造;以及制定高峰期的預案等。(圖:蘑菇街在 2015 年應對雙十一的架構,點選圖片可全屏縮放)我個人感受最深的是,以前的架構思路是出現問題,解決問題;現在有了個轉變,變成了預先思考在系統上可以做哪些事情,來避免問題的出現。第一個專案給了我機會去解決問題,跟著問題跑的能力。第二個專案給了我更深層次的思考,改變了跟著問題跑的思考方式,做事情有了前瞻性。高可用架構:蘑菇街從導購網站轉型到電商網站的過程中,遇到的主要技術挑戰有哪些?分別是如何應對的?蘇武:遇到的問題及挑戰個人認為有以下幾個方面。請求量的壓力。在轉型的過程中,網站的請求量還是快速往上漲,需要更多的資源去支撐,人和機器都是。業務複雜性增大。電商網站的業務相比導購來說,複雜度大很多。導購只是等於電商的頁面展示層,轉型後交易、支付、售後、客服、資料服務等系統都出來了,方方面面都複雜了。一致性與高可用能力。對應到系統上面,對資料的一致性、系統的穩定性和可用性要求都高了很多。降低耦合與提高服務化能力。蘑菇街 2013 年開始做電商的時候,我們的架構還是 LNMP 的,開發效率比較高,當然也出現了一些問題。比如所有的程式碼都在一個工程裡面,對資料庫的訪問也是直接訪問表,這樣其實系統的擴充套件性和穩定性都比較差,線上故障也多。在這個過程中考慮到時間短、人不多、業務需求多等限制,我們做了一些比較簡單的改進。業務垂直拆分。我們將交易和支付這類電商基礎的程式碼從之前的一個工程裡面獨立出來,變成一個獨立的工程,內部使用 HTTP 進行遠端呼叫。將核心功能服務化。將交易和支付系統的 DB 和 Cache 獨立,收斂對其的直接訪問,改成通過 HTTP 呼叫服務介面的方式。使用更好的硬體提升承載能力。在 DB 這塊我們做了硬體的升級,從 SSD 升級成了 PCIE 的儲存卡。硬體上的提升給我們贏得了更多的時間去改造系統。高可用架構:蘑菇街的使用者量和訪問量經歷過爆發式增長,為了保證快速增長下系統的可用性,你們有哪些經驗可以分享?蘇武:這幾年我們每個月都在增長,訪問量相比 2013 年漲了一個數量級,加上業務的複雜性變大,帶來的內部系統的呼叫量更大。2013 年:LNMP 架構上面說到蘑菇街 2013 年開始做電商的時候,我們的架構還是 LNMP 的,開發效率不錯。但等做完以後馬上到雙 11,結果當時因為幾個慢 SQL,全站出了半個多小時的問題。過後我們就開始做業務的垂直拆分,包括後面的 DB 和 Cache 都做了,然後在每臺 DB 都部署了慢 SQL 的監控工具,如果出現慢 SQL,直接 kill,同時每天也會給對應的開發傳送要求優化 SQL 的郵件。2014 年:服務化與 Tesla2014 年下半年的時候,就開始開發服務化框架了,這裡面的判斷如下。一方面當時我們所有的業務邏輯都在 PHP 裡面,這一層非常重,所有的程式碼都在一個工程裡面。到了後面除了幾個比較熟悉的開發,都不敢改比較底層的程式碼。這個時候線上的故障也比較頻繁,而且還是那種影響範圍廣的故障,牽一髮而動全身。另外一個方面是,前面 PHP 機器多了後,打到後端 DB 和 cache 的連線數暴漲,會達到 DB 和 cache 的連線數極限。我們也嘗試過在中間加一層 proxy 去解決問題,但新的問題也產生了,DB 的事務怎麼辦?cache 加了中間層 RT(round trip) 漲了 1 倍。再加上我 們對 PHP 沒有那麼熟悉,市場上優秀的人很少,感覺再下去就 hold 不住了。服務化框架是蘑菇街自己研發的,叫做 Tesla。開源方面有 dubbo 這樣優秀的產品,當時為什麼選擇自研?支援多語言。雖然會去 PHP,但是需要一個過程。短期內 PHP 還是會存在,所以需要考慮 PHP 端的支援。長遠看,需要支援多機房部署與跨機房呼叫。需要在穩定性保障和服務治理上接入其他的技術產品,自研會更加方便。選擇開源的產品也需要搞透其實現,有自己的駕馭能力,可能根據特定的業務場景做一些二次開發,這個時候你是貢獻給社群,還是走自己的分支?將來社群的新特性是否要合過來?2015 年:中介軟體建設2015 年的時候,分散式資料庫中介軟體和分散式訊息系統等都開始研發。資料庫中介軟體主要是為了進行讀寫分離和分庫分表,訊息系統主要是用在了業務解耦和非同步化上面。對於監控這一塊,除了基礎的機器監控,我們開發了一套可以給業務系統使用的監控產品,業務系統可以按照需要進行不同 metric 的埋點,可以進行聚合統計告警。我們還研發了資料庫資料增量產品,主要解決資料變更和離線資料匯出等問題。到這個時間段你會發現,基本上大型網站主流架構必須的技術產品我們都有了。當然電商的特色是每年都有峰值特別高的特殊時刻,為了應對這種峰值,我們在穩定性方面也根據往年一些經驗開發了一些系統:開關平臺。在業務系統中埋入開關程式碼。在高峰期的時候如果系統出現問題,可以直接在開關平臺關閉出問題的呼叫點。限流降級。系統限流是將服務能力之外的請求快速失敗,保證系統不會被打垮;降級是通過統計請求的 RT(round trip) 和 QPS 等,當這些指標觸發閾值時短暫的將某個服務降級掉,實現有損服務。限流是前置的,降級則有一個短暫的時間延遲,兩者會配合著使用。高可用架構:隨著電商業務越來越複雜,商品種類越來越多,你們在架構設計上如何為未來留有餘地?蘇武:我個人覺得應該從兩個大的方面去做了一些事情技術產品的準備,主要的目標是分散式的架構實現,像 Tesla 的研發,解決了服務層的分散式。分散式資料庫中介軟體的研發,提供分庫分表功能,解決了大部分的 DB 分散式問題。業務平臺的沉澱,在業務上實現分層架構。舉個例子:比如電商應用和電商平臺的分層,電商應用更加關注的是上層的業務,怎麼去做商品的展現,怎麼去做一個活動,怎麼去開發一個新的玩法。而電商平臺則更加關注業務規則和流程的構建,比如使用優惠券下單流程,支援虛擬商品交易等。比如大促的時候,電商應用可能會有會場、店鋪商品頁、banner 等形態,到了電商平臺這邊那他就只關注是否是虛擬商品,有沒有用優惠券,折扣多少等。(圖:電商應用與電商平臺的分層架構,點選圖片可全屏縮放)高可用架構:能否分享一下你們去年應對雙 11 的經驗?今年在備戰過程中會有哪些新的打算?蘇武:去年雙 11 是屬於蘑菇街服務化改造的過程,當時的狀況是,交易的業務平臺已經服務化完畢;支付及各類電商應用都還在 PHP 當中,其實還是一個不甚完美的局面。我們做了幾個事情:1. 架構梳理。技術團隊一起梳理當前架構的風險是什麼,這個梳理的結果將會指導後面去做什麼,會將結果進行分類。有一類風險是可以通過系統改造消除的,這種可以評估改造的時間點和風險,如果能趕得上雙 11 就進行改造;如果不行,則尋求另外的解決方案或者整理處理問題的預案。還有一類風險是短時間內改變不了的,對於這種問題,重點整理處理問題的預案,如果真的出問題,要求在短時間內去恢復。2. 系統容量評估。根據業務的目標以及業務的模型和玩法,將業務的資料對映到系統上面,將會得系統鏈路層面的容量目標。比如 1 秒鐘需要支援多少下單,根據這個目標再分解到一個個相關依賴的系統需要準備多少容量。3. 當知道準備多少容量後,接下來要做的就是去準備容量。這個涉及到一個度量容量的問題。我們採取的方式是線上的全鏈路壓測方式,用的是線上的真實環境,通過隔離壓測資料和線上資料做到資料不汙染,但是其他的環境和資源都是一樣的,這樣壓測出來的資料會比較準確。這個壓測難度還是比較高的,準備的時間比較長,整個壓測鏈路要打通需要各個團隊的配合,雙 11 之前全鏈路的壓測壓了有 5 輪之多。4. 講過前面的壓測後,會發現有些系統服務能力有問題,不能達到想要的目標,去改造時間不夠,加資源又解決不了問題,這種問題比較讓人頭疼。大家都聽過有損服務,這裡我們就做了一個事情,就是去梳理各類系統的依賴關係,並定義如下:一個系統如果不能提供有損服務,則定義為強依賴,反之為弱依賴。弱依賴如果有問題,可以通過開關和降級等手段摘掉,依賴於此的系統提供有損服務。如果是個強依賴,那麼無論如何都得想辦法去改造,讓它提供足夠的服務能力。通過這類梳理,我們發現 80% 以上的都是弱依賴,對這些弱依賴我們植入開關和降級程式碼,在關鍵時刻可以啟用,以確保整體穩定性。5. 在使用者請求入口,我們也做了限流方案,包括 QPS 限流和根據後端服務反饋的監控資料做的動態限流。限流主要是為了防止流量超出評估的容量,將系統打死。6. 另外我們梳理了大概幾百個預案。這些預案前面講到了是一些應對問題處理的策略,在全鏈路壓測的時候,在系統高峰期一一做了驗證(除了一些極端的預案,如 DB master slave 切換這類沒有做),當然在雙 11 當天只啟用不到 5% 的預案。今年的調整主要考慮將一些經驗和人肉乾的事情工具化、平臺化,另外也會嘗試新的保障方式。高可用架構:蘑菇街團隊及工程師文化是什麼樣的?你們推崇什麼樣的做事方式?蘇武:這個問題有點大。我們發展速度很快,需要做一些很有意思的系統,需要解決一些比較有難度的問題,當這些被一一完成後,帶來的成就感是非常大的,久而久之就是一種正向迴圈了。我們推崇做人簡單、開放,做事以技術和資料說話。高可用架構:在你看來,一位成功的架構師應該具備的最重要的能力和品質是什麼?對於未來想要成為架構師的程式設計師,你有哪些建議?我個人覺得是解決問題的能力和學習能力。解決問題的能力會讓技術廣度和深度的成長非常快;而學習能力則是不停找到系統最優解的前提。有一點需要明確,架構師不是個高大上的活,而是一份要幹髒活累活的工作。架構師需要思考方案,解決問題,實現核心功能。每個人都可以是自己負責的模組或者系統的架構師,在開始實現前多思考、多類比,我該選擇哪種方案,選擇的理由是什麼,優缺點是什麼,能不能有更優解?如果前提變了(時間、資源、需求),我會做哪些改變?另外一點就是,多解決問題。不需要是很高深的問題,碰到問題就去搞明白背後的原因、搞懂原理,經驗和知識的就會慢慢積累,自然而然就會成為架構師。

相關文章