恕我直言,微服務挺好,但不適合你

四猿外發表於2021-06-04

今天這篇文章我們繼續說架構師大劉的故事。

故事純屬虛構,別對號入座哈。

前言

大劉日子最近還不錯,經常午睡醒來,就繼續拿著手機看小說摸魚。大劉對當前所在的這家公司比較滿意。大部分系統已經成熟穩定,使用者量也中規中矩。雖然有些專案技術陳舊,但好處是沒啥么蛾子技術問題冒出來等著解決。

只是有時候大劉心裡會打鼓,公司盈利在下降,巔峰不在,也不知道這家公司能撐多久。除了偶然會冒出些對工作穩定的擔憂以外,大部分時候,大劉心情都是愉快的。直到他被領導叫到辦公室分派新任務的那一刻……

大劉的領導 CTO 老李,這些日子心情不是很好。他在的這家公司原本是個以傳統業務為主的公司。為了跟上網際網路時代,大老闆拍腦袋成立了個技術部門搞網際網路。雖說公司已經號稱觸網了,但是公司盈利基本還是靠傳統業務,技術部門只是打輔助的。沒有業務主動權,沒有盈利點,部門員工的工資卻都不低,老李的地位就可見一般了,經常受些冷言冷語的夾板氣。再加上,最近公司的效益也有所下降,眼見技術部門面臨著裁員的危險。老李危機意識被極大的刺激到了。

老李是個技術出身,但是離開一線編碼已經快十年了,每天的工作其實就是管理加玩概念。這幾年微服務的概念非常火爆,老李一直想著能搞點這種熱門東西,然後再拿著這些做出來的新概念技術,給那個不懂技術的大老闆展示下自己的兩把刷子,同時也能打響在業界的名聲,對自己的職業發展也大有好處。趁著構思部門前途這時當,老李認為這也是搞微服務的好時機,同時也想到了有微服務經驗的大劉。於是,大劉就被召喚進了辦公室……

經過了幾個小時的討論,大劉面帶無奈的接下了這個任務。這個任務是這樣的:

把公司裡幾套執行多年的核心繫統改造成微服務。

這些個老系統當初是按照幾萬使用者量的目標去設計開發的,雖然現在跑著沒問題,但是眼光要看長遠,產品和技術們將搞一套更高階的東西,目標是這套系統會被幾百萬人使用。

OK,微服務使用的前提出現了。

大劉來這家公司之前,在某電商大廠幹了多年,對微服務在電商系統中的應用這塊有實踐、有經驗。對微服務這塊,大劉是吃過豬肉、也見過豬跑,還被豬咬過……嗯,對,還被咬過不止一口兩口。所以,對改造微服務這個任務,大劉是硬著頭皮接下來的。

大劉雖然無奈,但是看在工資的份上活還得幹。不過槽還是要吐的,於是下班後大劉用了幾小時碼出了下面這堆心裡話。

正文開始(以下是大劉的第一人稱):

0

最近,經常有同事和我聊微服務,也屢屢期望對公司已有專案進行改造,希望能把所有專案改造成微服務方式。我對此經常很無語,也屢屢對這些人進行勸阻。

我認為,勸我改造微服務的人之中,有一些人純粹的對技術痴迷太深。更甚些,我甚至可以說這些人中的某些人就是純粹的自私自利。搞微服務難道不是為了蹭熱點,為自己的簡歷增色,為下一步跳槽漲薪做準備?何嘗想過微服務為公司帶來的各種壞處和因此而來的成本提升?另外有些人,則純粹是被外面鋪天蓋地的微服務概念給打暈了頭,被各種微服務成功故事洗了腦。這些人,把微服務當成了萬能藥,純粹就是腦袋犯了糊塗,陷入了唯技術論。

為了說明微服務不是萬能藥,這裡我們就先要說明下微服務的概念。同時呢,我們也需要詮釋清楚微服務的優缺點,看看什麼時候用微服務,什麼時候不用。

什麼是微服務?對於微服務的定義,網上眾說紛紜,並沒有一個權威的定義。但是在這些紛繁複雜,雲山霧罩的各種微服務洗腦文和說明文之後,總是有一個統一的基本面在:即微服務是一種利用分治法的思想,去把一整套非常複雜的業務邏輯給切分成多個簡單的業務問題,並採用模組化方法去實現組合的一種架構方法。

這麼說是不是還很抽象呢?好,我們們再更深入的解釋下,並順便把微服務的優缺點也全部一併說清楚。

1

首先,微服務是採用分治法思想,需要對業務邏輯做分解。做完分解後,還需要多個對應的實現模組去實現分解後的業務問題。這些模組的開發和維護,是都需要成本的。如果我們要搞微服務,考慮過開發維護成本嗎?

上面這圖表明瞭,從專案一開始,微服務的程式碼開發和維護每行平均成本就不少,隨著專案規模和系統複雜度的上升,程式碼的開發和維護平均成本才會緩慢下降並逐漸收斂到某一個值左右恆定。

而單體專案正好相反,一開始,單體專案的每行程式碼平均成本是比較低的,隨著專案規模和系統複雜度的上升,程式碼開發和維護成本會慢慢上漲,後續可能複雜度和開發成本會越來越高,一直衝上天際。

這時候,就不得不迫使人們去找到一種比較合適的方法,能把開發和維護成本降低到專案團隊可以承受的程度。

這就是引入微服務的意義所在。

但是,所有的專案會一直髮展下去嗎?所有的專案會永遠執行並擴充套件嗎?

有很多的架構師或者技術人員,在一開始做架構和系統設計的時候,不考慮實際情況,在公司給出一項很緊迫的任務之後,不去考慮實現時間和開發成本,上來就搞高大上,起手就是微服務,這現實嗎?

我們這些技術人員看過許多鼓吹微服務的技術書籍,也看到過很多微服務的“成功學”,但是他們的前提是什麼?他們對微服務的說法統統是建立在一個只有技術存在的完美世界裡,把現實世界他們認為的一切雜音都摒除在外,這合適嗎?

我們在做架構師之前,第一個考慮的應該是投入和產出。固然,我們從技術角度考慮,一定會要考慮可擴充套件性,可維護性之類的技術指標。但是,我們也需要根據當前專案的重要程度,盈利前景,還有可用伺服器資源等,作出自己的平衡來。

2

第二,微服務的另一個優勢是彈性化。什麼意思呢?就是我們在業務邏輯改變時,那些對應業務邏輯改變的功能的增刪改,開發和部署成本很低,可以像彈簧一樣,自由的縮減和增加。

並且,微服務裡最佳實踐是每個分出的模組應該都有自己的資料庫,和別的微服務並不共享任何資料庫。所以微服務本身認為,每個微服務模組的資料庫都可以不一樣。

比如我們開發一個電商網站,如果搞成微服務,大概如下:

如果我們的業務邏輯做了一些調整,比如,我們想要增加一個積分功能,那麼,我們只需要再增加一個叫做積分的微服務即可。

這就是微服務的便利之處。

但是,我們承認吧,並不是我們所做的每個系統都足夠大,都大到需要分解成更多更小的服務。那些不是太複雜的系統,它們憑什麼需要彈性化?憑什麼需要切分業務,從而搞出一大堆的專案出來呢?

另外,微服務的彈性化帶來的問題就是,我們需要管理因為彈性化所切分的許多小專案,需要搞出一套易用的自動化管理系統,需要把公司的底層基礎設定打造好,請問,這些成本,你準備付出了嗎?

在這個現實的世界裡,並不是一切圍繞著技術打轉的。固然,技術欠債會讓我們這些技術從業者感到分外的困擾和難受。可是,假如我們超前超度的使用了我們可能並不需要的超前概念和超前架構,同樣會使我們感到痛苦。

如果我們控制住了自己的技術慾望,我們是不是從自身也控制了一部分技術欠債呢?這是一個架構師應該要思考的地方,也是我們不應該濫用微服務的原因之一。

3

第三,微服務起手就是分散式。分散式我承認有各種各樣的優點,但是,分散式引發的各種問題和因此需要引入的各種技術解決方案本身也有自身的問題。

比如,分散式事務。在引入微服務前,我們作為架構師,一定要思考後續是不是可能出現跨服務的事務。兄弟,分散式事務大家都知道有多困難的。

按照微服務的標準,服務之間的通訊應該儘量採用簡單的 RESTFUL 協議。那麼,根據這種規範,如果我們採用了微服務方式架構,我們的每個專案都應該搞成 REST 服務。REST 服務本身就是無狀態的,現在,如果業務裡出現了嚴重依賴狀態的跨服務事務,想想吧,你會面臨什麼:

分散式鎖方案你是不是要考慮下?分散式互鎖後,出現了死鎖,你的追蹤策略是什麼?如果出現了競爭資源,導致服務狀態不一致了,你怎麼去快速恢復?資料腐蝕你有辦法嗎?

什麼?你告訴我我說市面上有很多成熟的分散式事務解決方案?別自欺欺人了,我們們都是搞技術的,請問,你說的是兩階段提交(2PC)嗎?好吧,大家都知道 2PC 那可憐兮兮的效能。

好吧,那三階段提交(3PC)呢?它的不一致問題曾經讓我們徹夜難眠。

搞 TCC 或者 SAGA 呢?對不起,因為最終一致性所新增的業務緊耦合的各種訊息和通知,會直接猶如 24 小時的夢魘,可能會是壓垮你的最後一根稻草。

微服務的提倡者老馬丁自己也說,微服務引入了最終一致性問題。

對於原來單體專案很簡單的事務問題,在微服務中,是一個令人皺眉的困難問題。所有微服務的開發者,在開發微服務程式碼之前,都需要考慮怎麼能探測到資料不一致的問題。否則,一定會萬分後悔。

那麼,分散式事務會不會一定會出現在微服務中呢?從目前來看,幾乎無法避免。為了搞定這些問題,微服務實現往往還需要伴隨著實現一整套構建在無狀態服務之上的呼叫鏈。

對於這些額外的開發成本,我們有必要嗎?是所有專案都需要的嗎?不是吧。這就是我們架構師需要考慮的問題,也是我們需要謹慎和妥協的地方。

4

第四,微服務互相之間是通過網路通訊配合起來來對外提供服務的。這就會帶來一個依賴性問題,即微服務非常依賴底層網路的健康。

如果網路通訊之間出了問題,整體對外的服務質量就會降低到極其讓人難以接受的程度。

並且,網路通訊天然就一定會帶來延遲。本來單體專案我們好好的,大家都是在內部互相通訊,延遲基本可以忽略不計。

現在,大家分開了,互相得遠距離打招呼,延遲動不動就來個幾十毫秒幾百毫秒延遲。這些延遲,我們也需要考慮在內,必須經過嚴格的測試才可以。

另外,網路通訊出現問題後的各種容錯方案,也必須考慮完善。以上說的這些,也都是一個合格的架構師必須在微服務引入之前,所要進行的綜合的考量。

5

其他:微服務的引入還有各種各樣的問題,包括:

  1. 額外引入的複雜性
    微服務在上面我也說過了,會帶來各種各樣的成本的提升,也會引入各種各樣的技術問題。這些最終就會導致整體系統複雜性進一步的提高。當複雜性提高的時候,為了保證系統的穩定,就需要整體技術團隊的靠譜,就需要技術人員的靠譜,就需要整體技術設施搭建的靠譜。在引入微服務之前,各位兄臺麻煩捫心自問下,這些貴公司有嗎?有這些團隊、這些設施、這些資源嗎?

  2. 分散式本身帶來的成本
    分散式本身就需要一整套完整的技術體系和設施去支撐整體分散式的建設。比如,以前單體專案只需要一個專案,直接人工上線就好了。現在呢,可能會出現幾十個上百個專案,這些專案如果全靠人工去做,會徹底讓團隊人員瘋掉。所以,就需要把整體釋出,部署自動化起來。這裡還僅僅是釋出部署所需要的,還沒有談維護問題,用《征服》劉華強裡的一句話說:”你有這個實力嗎?”

  3. 維護和監控微服務所需要的 DevOps 團隊
    微服務本身需要維護和監控,以確保執行的穩定和可靠。在微服務的最佳實踐裡,是非常推薦搞 DevOps 的。我暫且不說 DevOps 需要的對人員水平的高要求,我就說 DevOps 本身所需要的工作態度和責任心問題,自己家的運維團隊搭建是個什麼鳥樣子,運維成天忙死了再幹嘛,誰還不清楚嗎?整體運維的平均水準加上開發水平的要求,這個團隊搭建下來要花多少錢?公司捨得這些投入嗎?

  4. 微服務本身所需要的經驗
    微服務本身是很複雜的,從設計劃分模組開始,就需要架構師必須對架構設計和微服務本身對應的 DDD 領域驅動設計非常有經驗,能夠恰到好處的劃分出對應的模組。否則,一旦設計完畢,不巧把一些緊耦合的服務給硬是解耦成了不同的服務,那麼,這個後果對整個技術團隊甚至對整個專案團隊都是災難性的。同時,對於微服務的開發、維護、執行、保障以及運維,都需要技術團隊成員要有很豐富的從業經驗能迅速發現,定位,解決可能隨時出現的問題才可以。如果技術問題不能及時解決,那整體系統的體驗就可想而知了。但是,現在的經濟環境,現在的公司技術人員構成,確定能有這些很豐富經驗的人員來搞微服務嗎?

  5. 鏈路測試的方法
    我們上面提到過,為了快速追蹤定位死鎖或者共享資源的問題,微服務需要靠譜的呼叫鏈實現。那麼,這就引出的新的問題:我們如何搞全鏈路測試?我們是不是還得搞一套合適的全鏈路測試工具才可以?這全鏈路測試工具開發又需要花多長時間,需要投入多少人力?測試人員的水平是不是也需要得到一定的保證?

  6. 微服務日誌的爆炸
    微服務本身有多個節點,這些節點為了自己的安全執行和維護,需要很多自己獨有的日誌。這些日誌隨著微服務的增多,也越來越多,你如何存?如何查?如何刪?這些是不是都要考慮在內?

以上說的這些問題並不是否認微服務。

我只是砸給那些勸我沒事兒就搞微服務的人。對於這些什麼都不考慮,上來就說微服務的人,我認為都是非蠢既壞。

不管不顧現狀,沒事兒把微服務掛嘴邊動輒怎麼怎麼樣的人,我勸你悠著點。

最後

寫完之後,大劉感覺長出了一口胸中的悶氣,過完嘴癮,心裡也痛快了。現在大劉最擔心的是,這些文字千萬別被領導看到……

最最後

大劉的故事講完了,我再囉嗦一下。微服務肯定是先進的,但是都已經 2021 年了,不用我再和大家介紹微服務的優點了,那也太俗了。

希望大家看完能明白,並不是什麼新科技,熱概念都適合自己的團隊、自己的專案的。做一個合格的架構師、技術負責人,首先應該遵循的是 KISS 和 YAGNI 原則。

請各位技術人員永遠保持理智,我們要做的是選擇正確適用的技術而不是選擇自己最喜愛的技術。請不要做那種把簡單的事情往復雜裡做的技術瘋子。


你好,我是四猿外。

一家上市公司的技術總監,管理的技術團隊一百餘人。

我從一名非計算機專業的畢業生,轉行到程式設計師,一路打拼,一路成長。

我會把自己的成長故事寫成文章,把枯燥的技術文章寫成故事。

歡迎關注我的公眾號,關注之後還可以獲取演算法、高併發等乾貨學習資料。

我建了一個讀者交流群,裡面大部分是程式設計師,一起聊技術、工作、八卦。歡迎加我微信,拉你入群。

相關文章