【轉載】微服務是個壞主意嗎?

Binge-和时间做朋友發表於2024-09-05

引言


曾幾何時,我記得我的手指瘋狂地敲打鍵盤,與龐大而雜亂的程式碼庫搏鬥。那是巨石的時代,程式碼就像古老的城堡一樣,由一塊塊石頭砌成一個令人印象深刻的龐然大物。

幾年過去了,時代變了。開發人員口中的流行語變成了“微服務”。微服務革命——承諾成為我們的救世主。

我們被告知,透過將龐然大物分割成更小、自包含的獨立服務,我們將獲得無與倫比的可擴充套件性、敏捷性和可維護性。這聽起來是如此完美。

但是,當我把單體架構切換成微服務時,我不禁想知道:微服務的魅力真的像它所描述的那樣嗎?還是隻存在於遠景的海市蜃樓,只有當我們走近時才顯露出它的挑戰?

微服務的誘人承諾

還記得我們不得不與多個團隊協調只是為了進行微小的調整嗎?傳統的單體架構是後勤方面的噩夢。

每次更改都需要理解程式碼庫的大部分割槽域,與其他團隊同步,並希望一個小的調整不會引發多米諾骨牌效應。

但微服務開啟了新大門:突然之間,團隊可以獨立開發他們的服務了。

例如,使用者管理團隊可以實施新的身份驗證策略,而無需等待庫存管理團隊更新其產品列表方法。這種解耦不僅僅是在程式碼層面,它還延伸到了團隊動態。

O'Reilly 的一項調查發現,採用微服務的組織在團隊協作方面提高了63%。每個開發人員都成為其領域的大師(從字面上看,考慮到領域驅動設計實踐)。

在我們之前的一個專案中,我記得“黑色星期五”大促銷活動時引發的混亂。我們的單體應用難以應對大量湧入的使用者,導致所有功能的效能下降,而不僅僅是結帳流程。

微服務很好地解決了這種不平衡的需求。你只需簡單地在負載下擴充套件服務,而無需為整個應用程式過度配置資源。

想結賬的使用者激增?沒問題,擴大結帳服務規模。

宣傳影片病毒式傳播?沒問題,提升媒體服務,不影響觸及其他服務。

思科的一項案例研究顯示,使用相同數量的資源的情況下,使用微服務架構設計的應用程式可以處理多達 20%的負載。

不那麼迷人的現實

雖然許多人認為微服務是解決軟體開發問題的靈丹妙藥,但作為一名遠端開發人員,我對這種架構風格的嘗試經常感覺像開啟了潘多拉的盒子。

在虛擬茶水間的閒聊和一行行程式碼之外,這個故事總是充斥著無數希望、頻繁的正面交鋒以及相當多的啟示。

當我將我的第一個專案過渡到微服務時,我突然意識到,「將一個應用程式拆分為多個服務並不是簡單的“分而治之”」 。

隨著拆分而來的是管理這些離散服務的責任。有一次,我部署了一個新的微服務,突然間,系統的其他部分失去了對它的跟蹤——這是分散式系統中服務發現(Service Discovery)的臭名昭著的挑戰。

此外,資料一致性也成為一場艱苦的戰鬥。

我再也不能依靠單個資料庫事務來確保一切正常。因為每個服務都在管理自己的資料,我發現自己陷入了分散式事務的泥潭之中。

然後是失敗。當一項服務失敗時,連鎖反應通常會導致其他服務發生級聯故障。
理論上讓服務進行通訊,聽起來很簡單。

但問題是:分散式系統引入了延遲。

一天晚上,我正在除錯一個異常緩慢的操作,卻意識到罪魁禍首是服務之間的大量同步呼叫。等待下一個請求的次數增加了。

這需要改變戰略。

雖然透過事件進行非同步通訊減輕了一些痛苦,但它也帶來了挑戰,例如確保事件的順序。
被吹捧的模組化承諾往往與效能相悖。雖然微服務可以簡化流程,但與傳統的單體應用相比,它們也可能導致通訊延遲。

噩夢迴圈:部署混亂

作為 CI/CD 的堅定倡導者,部署單個服務的承諾感覺就像一個夢。

但現實很不一樣。最初的幾天尤其混亂。

使用多個管道時,一個服務中的更改有時需要與其他服務進行協調。還記得你每天都為之頭疼的版本相容性問題嗎?有了微服務,跟蹤哪個版本的服務A與服務B相容成為了一種日常儀式。

我開始懷念單體架構了

帶有一系列服務和資料庫陣列的微服務,常常感覺就像一塊不斷移動的拼圖。有很多個晚上,我發現自己由於無法預見的整合問題而恢復程式碼,或者梳理日誌試圖找到哪個服務是薄弱環節。

與巨石時代形成鮮明對比的是,在鐵板一塊時,變化儘管規模較大,但具有一定的可預測性。
工作流程是線性的,那麼部署呢?好吧,他們感覺更受控制了。

如果你曾經嘗試透過一串 Slack 訊息來傳達一個複雜的想法,你就會欣賞直接溝通的益處。與此類似的,在單體架構中,模組之間的程序內通訊的簡單性是直接、無縫的,並且通常被認為是理所當然的。沒有網路呼叫,沒有延遲,沒有丟失請求。一切都在應用程式的範圍內正常工作。

使用微服務,服務間通訊感覺就像試圖與分佈在各大洲的團隊成員進行 Discord 語音聊天,每個人都在與自己的網際網路困境作鬥爭。

當然,這是可行的,但這些小問題會讓你懷念一切都在一個屋簷下的時光。當公司要求他們的開發人員回辦公室坐班時,我理解了:它確實有它的好處,尤其是在即時溝通方面。

權衡:我們得到了什麼,失去了什麼

微服務的主要優勢之一是能夠專注於特定的功能。我記得我被分配到一個專門負責使用者身份驗證的團隊。解耦的特性使我們能夠完善機器中的一個齒輪。

不久前,我們的單體應用中的一個小模組故障導致了嚴重的中斷。對於微服務,每個服務都充當其隔離的故障點。我見過一些特定微服務出現當機的例項,但多虧了架構,整個應用程式得以繼續執行,使用者對此幾乎沒有感知。

當單體更好時

管理微服務感覺就像同時處理十幾個Slack頻道。每個服務都有自己的日誌記錄、監視和部署過程。相比之下,單體架構有一個固定的流程。

微服務通常意味著多個資料庫。雖然這看起來很棒,但確保資料一致性卻是一場噩夢。在單體架構時代,一個資料庫意味著一致性。這就像在 Discord 中有一個執行緒,每個人都在更新。我經常發現自己懷念這種統一性提供的便利。

然後是整體除錯。

還記得嘗試透過相互連線的微服務跟蹤bug嗎?這就像追溯無數的 Discord 對話來找到一條訊息。但在單體架構的設定中,錯誤日誌是集中的,因果關係更加清晰。

總結:微服務之旅中的反思

當我回顧自己在微服務領域的嘗試時,我發現這條道路充滿了挑戰、得失和可以從中學習收穫的寶藏。以下是我在微服務之旅中獲得的3個主要收穫。

「1. 明智地接受複雜性」

深入微服務不僅僅是一個技術決策——這是對複雜性的承諾。有時,我們會覺得自己只是為了順應潮流而打破了一個體系。並非每個應用程式都需要由相互連線的服務組成的網路。正如Sam Newman在《構建微服務》中提到的那樣,架構需要一定的先決條件,如果沒有這些先決條件,它可能會矯枉過正。

「2. 靈活性是有代價的」

是的,微服務承諾了靈活性,但要實現這一點,也需要付出沉重的代價——不僅在基礎設施方面,而且在認知負荷方面。每項服務都有自己的領域,需要專門的關注。

「3. 沒有放之四海而皆準的方法」

架構決策不能脫離業務需求。靈活的初創公司的需求與傳統的企業應用程式截然不同。雖然經典案例研究(例如 Netflix 著名的微服務轉型)很有啟發性,但必須認識到,適用於一個人的方法不一定適用於所有人。

變身為技術弄潮兒可能很誘人。成為科技領域重大變革的組成部分有一定的吸引力。但作為程式碼的守門人,我們需要抵制盲目接受趨勢的誘惑。批判性評估、理解趨勢背後的“原因”,並權衡其與我們的特定背景的相關性至關重要。

Slack 訊息、GitHub 儲存庫和 Discord 討論已成為我們許多遠端開發人員的新飲水機。在各種噪聲中,讓我們記住定期聚焦,反思我們的選擇,並確保我們不只是追逐趨勢,而是有目的地制定經得起時間考驗的解決方案。

相關文章