如何避免單點風險:基於實踐經驗分享服務拆分原則的一些思考

  • 緣起:系統崩了

  • 具體情況:1%的請求影響了剩餘90%的請求

  • 架構演進:拆分熱點服務【進程級隔離】

  • 覆盤

  • 總結

  • 拆服務的經典實踐

 


不能變形的變形金剛也叫變形金剛?

緣起
系統崩潰了?別驚慌!這裏有快速恢復的方法!
分析發現,網站崩時服務X被流量打垮,繼而依賴服務X的其它服務開始互相“踩踏”,最終崩潰。
網站崩時,服務X的QPS過高,實際達到了業務gateway服務的2倍~~

 

出故障時的系統結構概覽:

 


一個請求的生命週期

具體情況:1%的請求影響了剩餘90%的請求

 

相同時段之前崩掉服務的情況:

 

業務gateway的流量爲什麼會遠小於服務x的流量是不是合理?

 

業務服務與基礎數據服務耦合在一塊是不是合理的??

 


接口響應時長, 也從毫秒級, 快速退化到秒級

 

圖片

一個查Redis緩存的請求耗時7708ms

圖片

org.springframework.web.servlet.FrameworkServlet.doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)

解決方案:拆分熱點服務【進程級隔離】+水平擴容+k8s HPA

https://www.processon.com/view/6447cd7e8e188d4a087d3d1e

架構升級後服務的效果:
1、架構更合理了
2、接口響應時間更短

 

 

覆盤
1、這是誰的問題?
這是服務的穩定性的問題。

2、有什麼問題?
一個服務崩了,導致整個業務系統崩了。

3、解決的思路是什麼?
把整個業務系統依賴的基礎拆出來。

總結
一個基礎服務不可用,導致整個業務系統不可用。
然後,通過把這個基礎服務拆成一個單獨的服務,來解決這個問題。

 

思考
服務拆分的原則是什麼?

在分享關於服務拆分的思考之前,讓我們先來談一些相關的概念吧。

什麼是架構?

軟件架構是指軟件系統的頂層結構,而架構設計的目的是爲了解決軟件複雜度,是爲了使軟件項目更加可靠、高效和可擴展,以便於持續迭代。
架構的思考來源於對生命週期的識別,以及對生命週期的拆分。如果沒有生命週期拆分的思考,就不能算架構。什麼是微服務架構?
微服務架構是一種架構模式,它提倡將單一應用程序劃分成一組小的服務,服務之間互相協調、互相配合,爲用戶提供最終價值。微服務架構的本質是分佈式系統。
來看看Martin Fowler大佬的理解:

 


上述英文的三個關鍵詞分別是:small、lightweight、automated,這基本上濃縮了微服務的精華,也是微服務和SOA的本質區別所在。

微服務拆分的目的是什麼?服務拆分的目的是將龐大複雜的系統拆分成小而簡單的服務,以便更好地應對持續迭代的需求。
這樣做的好處在於,各個服務可以獨立運行,降低了彼此的耦合度,使得後續的開發、部署、測試和維護等工作更加容易進行,從而提高了系統的可靠性、可擴展性和可維護性。因此,服務拆分不僅是爲了簡化系統,也有助於讓系統更好地適應未來的變化

微服務拆分的原則:化大而複雜爲小而簡單。

進行服務化拆分,把一個大而複雜的問題化解爲多個小而簡單的問題,服務之間通過契約來約定依賴,做到服務獨立發佈和演進。
微服務到底有多微,是個仁者見仁,智者見智的問題,最重要的是團隊覺得是合適的。但注意,要達成“團隊覺得合適”的結論,至少還應該遵循以下兩個基本前提:

  • 業務獨立性

首先,應該保證微服務是具有業務獨立性的單元,並不能只是爲了微而微。關於如何判斷業務的獨立性,也有不同的考量。譬如可以將某一個領域的模型作爲獨立的業務單元,譬如 訂單、商品、財務、售後等;也可以將某業務行爲作爲獨立的業務單元,譬如發送郵件、不同數據庫之間的業務數據同步等。

  • 團隊自主性

其次,考慮到團隊的溝通及協作成本,一般不建議超過10個人。當團隊超過10個人,在溝通、協作上的所耗費的成本會顯著增加。當團隊成員超過10個人的時候,可以考慮繼續再劃分子團隊,讓不同的子團隊承擔獨立的工作。

微服務拆分過程中的坑

  • 微服務拆過細,過分強調“small”
  • 微服務基礎設施不健全,忽略了“automated”
  • 微服務並不輕量級,規模大了後,“lightweight”不再適應


如何拆分?

對拆分依據的思考,實際上是在問:“服務的粒度如何界定”。
針對微服務拆分過細導致的問題,建議基於團隊規模進行拆分,類似貝索斯在定義團隊規模時提出的“兩個披薩”理論(每個團隊的人數不能多到兩個Pizza都不夠喫的地步)。
那麼,以“三個火槍手”爲原則的微服務拆分粒度,即一個微服務三個人負責開發。當我們在實施微服務架構時,根據團隊的規模來劃分微服務數量,如果業務規模繼續發展,團隊規模擴大,我們再將已有的微服務按這個原則拆分。
“三個火槍手”的原則主要應用於微服務設計和開發階段,如果微服務經過一段時間發展後已經比較穩定,處於穩定期了,無需太多的開發,那麼1個人維護1個微服務甚至幾個微服務都可以。
拆分的思路

基於“三個火槍手”的理論,我們可以計算出拆分後合適的服務數量,但具體怎麼拆分也是有技巧的,並不是快刀斬亂麻隨便拆分成指定的數量就可以了。常見的拆分方式有如下幾種,接下來我們一一介紹。
(1)基於業務邏輯拆分
將系統中的業務模塊按照職責範圍識別出來,每個單獨的業務模塊拆分爲一個獨立的服務。
(2)基於可擴展拆分
將系統中的業務模塊按照穩定性進行排序,將已經成熟和改動不大的服務拆分爲穩定服務,將經常變化和迭代的服務拆分爲變動服務。剛開始,穩定的服務粒度可以粗一些,即使邏輯上沒有強關聯的服務,也可以放在同一個子系統中。例如,將“消息推送服務”和“升級服務”放在同一個子系統中。
這樣拆分主要是爲了提升項目快速迭代的效率,避免在開發的時候,不小心影響已有的成熟功能,引發了線上問題。
(3)基於可靠性拆分
將系統中的業務模塊按照優先級排序,將可靠性要求高的核心服務和可靠性要求低的非核心服務拆分開來,然後重點保證核心服務的高可用。具體拆分的時候,核心服務可以是一個,也可以是多個,只要最終的服務數據滿足“三個火槍手”的原則就可以。
這樣拆分可以帶來如下幾個好處:

  • 避免非核心服務故障影響核心服務

  • 核心服務高可用方案可以更簡單

核心服務的功能邏輯更加簡單,存儲的數據可能更少,用到的組件也會更少,設計高可用方案在大部分情況下要比不拆分要簡單得多。

  • 能夠降低高可用成本

    將核心服務拆分出來後,核心服務佔用的機器、帶寬等資源比不拆分要少得多。因此只針對核心服務做高可用方案,機器、帶寬等成本比不拆分要節省較多。

    (4)基於性能拆分

基於性能拆分和基於性能拆分類似,將性能要求高或性能壓力大的模塊拆分出來,避免性能壓力大的服務影響其它服務。
常見的拆分方式和具體的性能瓶頸有關,可以拆分Web服務、數據庫、Cache等。
例如,電商的搶購,性能壓力最大的入口的排隊功能,可以將排隊功能獨立爲一個服務。

以上幾種拆分方式不是多選一,而是可以根據實際情況自由排列組合。

小結
服務拆分的目的是爲了提高軟件項目的可靠性、效率和可擴展性,以便更好地應對持續迭代的需求、支撐軟件的增長。通過將大型應用程序拆分成小的、獨立的部分,可以降低系統複雜度並提高整體質量。這種架構設計也有助於快速開發、測試和部署代碼,從而提高開發團隊的工作效率。
如果無法實現上述的目標,就需要重新考慮是否有必要進行服務拆分。


引用
https://martinfowler.com/articles/microservices.html
https://time.geekbang.org/column/intro/100006601?code=SWmCO2yChZKMsxvoZphPgPyr8SX0c6wLhHZBcxyOZFs%3D&source=app_share
《從零開始學架構 照着做,你也能成爲架構師》
《微服務 架構與實踐》
《聊聊“架構”》
https://www.bilibili.com/video/av71345202

https://mp.weixin.qq.com/s/f1sEprXHw1ciYljH5PP3yw

 

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