關於微服務的一點思考

在 reddit 上看到一篇文章(被標題吸引了) Monoliths are the future[1]——作者在吐槽微服務。

And then what they end up doing is creating 50 deployables, but it’s really a distributedmonolith.

作者說,他們改造後的 50 個微服務,其實就是 50 個分佈式的單體服務。進行微服務改造後,他們原來的問題並沒有解決或減少,反而帶來更多新的問題。最後他們又改回去單體服務。

這篇文章其實是個標題黨,內容本身沒什麼好看的。微服務改造失敗,這大概率是作者所在的團隊錯誤應用微服務的問題——微服務不是銀彈

在過去的幾年,微服務這個概念很火,容器、k8s、ServiceMesh 各種微服務基礎設施如火如荼。使用微服務來構建應用程序似乎成了一種理所當然的標準——很少有人停下來思考:什麼時候該用微服務?還有更重要的——什麼時候不該使用微服務?

首先,當我們說起微服務的時候,我們是在說什麼?

微服務是一種應用於組件設計(服務如何分組)和部署架構(服務如何部署和通信)的軟件架構風格。它利用模塊化的方式組合出複雜的大型應用程序:

  1. 各個服務功能內聚,實現與接口分離。
  2. 各個服務高度自治、相互解耦,可以獨立進行部署、版本控制和容量伸縮。
  3. 各個服務之間通過 API 的方式進行通信。
  4. 各個服務擁有獨立的狀態,並且只能通過服務本身來對其進行訪問。

其次,當我們實現微服務的時候,我們想要得到什麼?

從上面對微服務特點的描述不難看出,實現微服務可以帶來的好處有:

  1. 迭代升級更加敏捷:不同功能的服務可以獨立變更,不相互影響。
  2. 服務容量更加彈性:可以根據具體的負載單獨對某個服務進行擴容、縮容。
  3. 系統可用性更高:某個微服務故障不會導致整個服務故障。

然而,實現微服務是需要權衡利弊(trade-off)的。

程序員知道種種優勢,卻對代價一無所知。

—— Rich Hickey (Clojure設計者)

  1. 原來的單體服務如何切分?這是一個關鍵問題——切分得不好,就會像前面那篇文章的作者一樣,遇到一個單體服務變成多個單體服務的問題。
  2. 服務切分後,API 會成倍增加。這會引入各種 API 的管理問題,比如各種健康監控、優先級、權限等。
  3. 本地調用變成遠程調用會引入了網絡延遲,進一步引入了分佈式事務。
  4. 微服務請求如何自動路由?調用鏈路如何追蹤?如何自動進行熔斷降級,防止雪崩?

等等。引入微服務的代價就是——整個系統的複雜度大大提高。

在我的經歷/經驗中,從單體服務到微服務其實是公司內組織架構轉變的結果。

遙想當年,有一個 web 程序,最開始只有一個組幾個人在做,剛開始業務也比較簡單,所以所有相關業務都在上面。

後來業務發展良好,開發人數持續增長,業務越來越多、越來越複雜,隨後開發人員根據具體業務/功能被拆分成幾個小組。

有很長一段過渡時間,所有的變更還是在這一個程序上進行。

這個程序調用量很大,而且可能因為業務 A 的 bug,影響了其他所有業務,每次變更都有不小風險。

這個程序部署的機器比較多,每次變更的時間都比較長。

開發人員越來越多,但是沒能做到隨時獨立變更——每次上線都要進行協調,然後合併多個人的代碼一起上線。有時候解決代碼衝突就要花掉一整天的時間。上線的時候,如果發現某個功能有問題,需要進行回退——其他功能就算沒問題也只能一起回退——業務多而複雜的時候,這種情況很容易出現,非常影響迭代速度。

這種情況下,亟需一種能解決組內自治、快速迭代、跨團隊合作的軟件架構——沒錯,就是微服務。

設計系統的架構受制於產生這些設計的組織的溝通結構。

— M. Conway

如果只是一個緊密的小團隊,在引入微服務之前,要三思——不要只顧追求時尚,不要人云亦云,適合自己的才是最好的。


分享到:


相關文章: