決定啟用微服務架構,準備一個月後最終還是放棄遷移到微服務

經過一個月的準備和調查,我們取消了遷移,仍然使用單體模式。對我們而言,微服務不僅幫不上忙,反而會影響到開發計劃。

我們瞭解微服務大約是在一年前,但是很驚訝地發現它並不適合我們。本篇文章把我們的經歷寫出來,可能會對大家有借鑑意義。

發現問題以及早期妥協

我們嚴重依賴第三方

我們的應用是整合外部現有產品和業務規則給用戶展現一個友好界面的 UI。客戶是一家 UWP App,後臺有相應服務在第三方域和我們之間交換數據。

對第三方的依賴嚴重影響我們選擇微服務。例如,應用經常要在不同域之間轉換功能,使得第三方域看起來像是完全不同的一個域,如果在我們之間有一個單一服務情況還不算太糟。

然而,整個域交換在分解成多個微服務過程中就看起來很怪異了。

是我們的微服務跟第三方的分解不同嗎?我們複製了所有服務的前後端需求嗎?還是我們分解了自己的微服務,仍然需要一個微服務從第三方獲取信息?所有這些問題看起來都跟微服務指南相背離。

我們和第三方合作很緊密,經常一起協作發佈版本。微服務的好處在於每個團隊都可以不受影響獨立發行服務,而跨公司合作則失去了這種好處。

微服務另外一個好處在於,每個團隊只需要完整設計自己的業務問題。而我們,作為一個和第三方完全獨立的公司團隊,這種重構看起來不可行。

我們不能有效分離微服務

我們實在找不出應該從哪個單體應用下手。於是我們在域模型之間連線,以決定要創建哪些微服務。

然而,一旦這麼開始做,發現很多共享業務邏輯影響著微服務域的劃分。如果將微服務劃分的更細小,只能帶來更多的耦合關係,到處都需要消息總線,消息可能會出現大爆炸。

原因在於我們的單體式應用是為一個業務邏輯服務的。我們為用戶方便創建了跨域和組的很多工作流,本質上,UI 在過去四年中就是將各種東西整合到了一起。

另外,我們還誤解了微服務如何被隔離,以及低估了服務之間正確邊界選擇的重要性。

唯一能做到的就是為了實現一個標準功能,從而需要將所有相關微服務同時升級,由此要求每個微服務都不能被某個單獨團隊擁有。

共享微服務

我們大約有 12 個開發人員分佈在兩個功能團隊和一個支持團隊。工作波動性很大,沒有專職負責團隊。所有團隊同時接觸同一批代碼很正常,不能將某個微服務指定給一個團隊。

考慮架構時候一定要記得 Conway's Law,其意思是軟件架構會模仿組織和團隊架構增長。

微服務架構對於不同團隊負責不同業務邏輯是比較有效的,然而,共享代碼功能的工作模式最好採用單體式架構。

平臺並沒有準備好

各種問題意味著至少六個月內,需要在 IIS 內並行運行微服務和單體式應用。

我們不會訪問與微服務相關的工具,如容器、Kubernetes、服務總線、API 網管等,也就意味著與其他微服務之間通訊有很大障礙。

因此,我們決定每個微服務都複製與存儲層轉換相關讀服務的共享邏輯。因為不能正常拆分服務,也就意味著必須承擔大量複製工作量。

例如,對於某個複雜而且基礎的業務邏輯,必須複製黏貼並維護至少 4 個計劃中的微服務。

沒有未來清晰圖景

開發團隊只有六個月內粗略的構想,而且業務更改也很頻繁(業務更改需求也是司空見慣的事情),這些讓微服務化更加充滿不確定性,因為即使在短期也無法預知會出現什麼鏈接。

微服務之間的複雜性會增加嗎?花了幾個月分離的服務會回到過去嗎?儘管我們今年早些時候做過一些 PoC,但是因為業務需求的更改不得不放棄。

架構緊耦合

我們只有一個很窄的時間窗口,剛好能把單體式應用分解成列出來的微服務,而且沒有冗餘時間應付可能出現的改變,也沒有 Plan B,我們被自己給卡住了。

因為我們在計劃階段就發現了很多問題和挑戰,更別說實施階段了,開發團隊非常有壓力。

缺乏經驗

考慮到風險和時間壓力,而且架構師和實施專家也都沒有任何特殊經驗,加上沒有標準工具能用,我們只能靠自己來實施,這些都更加惡化了情況。

和其他微服務大拿溝通後,他們也都發出了很多警告,並給出了不少以前並沒有的架構建議,指出了我們在域模型之間畫線的順序。

到目前為止,由於時間緊任務重,我們的計劃包括了很多不同於標準微服務的妥協方案。

因為缺乏專家,這看起來更像一條不歸之路,開發團隊越來越焦慮。

再次拷問我們的目標

是否解決了痛點

一旦前方佈滿了困難,就失去了目標,我們暫停下來,意識到我們並沒有搞明白為什麼要這樣做。

我們沒有列出痛點,而且不清楚這樣做是否可以解決痛點。更甚,微服務有可能會給我們帶來新的問題。

我們開始反思,我們從中會獲得什麼好處?能解決什麼問題?我們召開了更多會議討論它,但一直沒有明確的答案。

最後,我們發現在討論微服務過程中我們忽略了一個很重要的痛點,而且沒有足夠的時間來解決這個問題,也就是我們不能考慮微服務或者其他東西了。

潛在收益是什麼

這時候我們開始反思微服務一般意義上會帶來什麼好處?

自治

微服務使得團隊可以控制全棧提供一個功能。這種區隔會減少不同團隊之間協同的次數,互相不影響對方的工作。

使團隊更加專注

單體式應用中,團隊可以專注於所有任務。而採用微服務後,則是某項業務流程的專家。

他們會理解自己區域內的業務規則和需求,知道軟件棧如何搭建,當發生改變時會非常有信心完成。

易於擴展

有了微服務,可以根據性能需求擴展服務規模。而在單體式應用中,儘管也可以水平擴展服務,但是不能獨立擴展單體應用的模塊。

微服務粒度可以增加或者減少服務能力。也許當發現性能問題時,可以參與其他工作,或者稍微喘口氣。

易於回滾

每個功能只需要修改單一微服務,而且可以不影響其他團隊工作進行回滾。另外微服務還可以減少單一錯誤對整個系統的影響。

易於迭代

如果有一個擴充系統的,每個發佈都很花時間並且有風險,那麼就需要大量工作處理每次發行時的問題。

微服務可以減少溝通時間和成本,團隊可以各自確定合適時間。

採用最佳技術

團隊依賴微服務可以選擇最佳技術方案。而單體式卻很難升級。

易於升級

大型應用升級都不是一件容易的事情。尤其是要在多個團隊之間協作。相互隔離的微服務可以每次只升級一個服務,更容易控制風險。

風險保護

微服務可以將頻繁變化和很少變化的服務分隔開,減少意外發生的風險。

粒度減小

小型化服務更易於理解,而且可以保持設計一致。對比來看,單體式應用會因為不同團隊的意見不統一帶來不一致性。

優勢彙總

微服務有很多優勢。但是我們能從中獲得什麼?

最終,對於無法改變或者妥協的架構只能放棄這些優勢。我們失去了微服務帶來的隔離性。與第三方的合作減弱了從服務不相關性中帶來的好處。

權衡

大炮打蚊子

微服務也並不都是優點,有一長串需要考慮的問題。

例如,日誌,監控,異常處理,容錯,回滾,通訊,消息格式,容器,服務發現,備份,遙測,報警,跟蹤,工具,共享,文檔,擴展,時區,階段,API 版本,網絡延遲,健康檢查,負載均衡,CDC測試,等等。

如果沒有微服務平臺,我們要自己面對所有上面列出來的問題。因為有痛點才要轉向微服務,但是不但沒法從中獲益,還要面對一堆轉向微服務帶來的問題,我們是何苦來呢?

微服務只是名義

下圖是我們現在單體式應用和微服務的對比。架構上來看,新架構很像單體式,各個組件還是緊耦合,也許我們只是用了微服務的標籤。

決定啟用微服務架構,準備一個月後最終還是放棄遷移到微服務

單體式一定很差嗎

好像“單體式”就意味著落後,“微服務”就意味著先進。但是從開發團隊來看,我們的單體式應用運行良好,基本沒有什麼問題。

我們有很好的 CI/CD 配置,易於配置和回滾。分支和測試策略確保問題都被提前解決。

似曾相識

此時,似乎有些熟悉的感覺。在我以前從業經驗也有過類似的經驗,但從沒稱為微服務,儘管並不完全符合微服務的規則,但是的確解決了問題並帶來類似的好處。

5 個人的小團隊帶領 200 人的開發者。這是一個巨大的 C# 應用,大概 5% 的工作通過單體式共享,其他的共享兩節點服務。

我們也不喜歡單體式,工作起來很慢,編譯,測試,架構改變的很快經常看到不同的同事出現。

有時候因為一個從未聽過的同事辭職了從而延遲了整個項目,技術更新因為要和整個公司同步需要幾個月,Pull 申請需要整個系統批覆需又要幾個星期。

同時,有兩個服務規模很小,我們可以很好地控制、部署、架構它。一旦有性能問題,會懷疑實例數量直到解決底層問題,很少麻煩其他團隊。

我們團隊主導了前後端開發語言的選擇。總之,我們很專注於一個很窄的業務邏輯,每個人都成為了專家。

技術之外

越瞭解微服務,越發現其不太適合我們。我們是不是太為了技術而技術了?

還有很多其他問題沒考慮:

  • 有沒有專注業務邏輯的團隊?
  • 是否能夠清晰劃分域和微服務?
  • 工作在所有團隊之間是否平衡?
  • 團隊負載是否均衡?
  • 單體式困難是否被分解到其他工作中?

覆盤

遷移到微服務是個大爆炸,大家都停下功能開始想如何分解單體引用,即使前提還不具備。

後來證明這不是個好方法,有可能還是個倒退。首先創建所有微服務,然後設置架構並忽略了團隊的架構。

假如我們開始時考慮團隊和業務邏輯結合,等架構成熟,並等微服務自然顯現,會更好。而且新的業務需求出現,可以直接被放在一個新服務中。

強制上微服務,也意味著需要選擇每個微服務的大小。一些文章建議每個微服務至少按照一個團隊的支撐設計。其他的則建議越小越好,一旦需要更改,很短時間內就可以完成。

領導層決定按照工作域劃分,如果需要再細分。這個決定導致上面出現的問題。後來覆盤時發現如果等待微服務自然出現,其大小其實最合適。

取消

隨著預定時間一天天臨近,我們團隊持續發現越來越多的問題。上線四天後,仍然看不到預期的效果。於是召開了一次會議,最終取消了微服務計劃。

取代行動

微服務的熱度消散,也就意味著我們沒有做好必要的調研。拋棄了微服務後,我們也有精力去調研其他方案。

最後,我們決定在單體應用內部劃分成不同項目,更好地劃分了架構和耦合關係。

另外這種架構使得域模型更加清晰,使得未來考慮微服務更容易。

結論

領導層上微服務的倉促決定並沒考慮清楚挑戰和目前狀態。評估後,發現微服務並不適合我們,需要更多的妥協。

這些折衷方案把微服務帶來的好處都抵消掉了。微服務並不考慮非技術因素,例如團隊結構和工作量。

幾個月調研後,我們拋棄了微服務嘗試,決定對已有的單體式應用做一些更適合的微調。


分享到:


相關文章: