當前位置:
首頁 > 知識 > 2018 瘋狂微服務之死

2018 瘋狂微服務之死

近期微服務的話題非常火爆,有時可謂非常「瘋狂」:


Netflix 在 devops 上做得很棒,同時 Netfix 也採用微服務。因此:如果我也用微服務,那麼我也可以在 devops 方面做得很好。

很多情況下,為了解決手頭的問題,我們付出了巨大的努力採用微服務模式,但是並不清楚它的成本和收益。

接下來我將詳細介紹什麼是微服務,這種模式吸引人的原因,以及它所面臨的主要挑戰。

如果你正在考慮微服務是否適合你的模式,我會在文章的最後用一系列簡單的問題來幫你做出選擇。

2018 瘋狂微服務之死

什麼是微服務,它為什麼如此受歡迎?

首先從最基本的開始了解。下圖是一個假想的視頻共享平台的實現方式,左側是傳統的整體式架構(單個巨型單元),右側則是微服務:

2018 瘋狂微服務之死

兩種模式的區別在於第一種是整體式架構,只有一個大單元。第二種則由多個小單元構成,每個小單元都是獨立的服務。

上圖已足夠細緻,從中很容易找到微服務模式的吸引力所在。以下是微服務架構的具體好處:

獨立開發:小型的獨立組件可由小型的獨立團隊構建。一個小組可以專門負責開發「Upload」服務,不用去管其他服務。每個組件的功能變得簡單,這樣一來,開發人員了解組件的時間大大減少,更容易開發新功能。

獨立部署:每個單獨的組件都可以獨立部署。這樣一來發布新功能的速度就更快,風險也更小。假設「Streaming」組件修復了 bug 或者新增了功能,那麼部署時並不會影響其他組件。

獨立擴展:每個組件可以獨立地進行擴展。在新節目剛發布的繁忙時期,可以擴展「Download」組件,以支持增加的負載,而不必擴展所有組件,這樣一來擴展更具彈性並且降低了成本。

可重用性:每個組件各自實現一個小的、特定的功能。這意味著它們可以很容易地適用於其他系統、服務或者產品。「Transcode」組件可以被其他業務單元使用,甚至可以改寫成一個新的業務,從而為其他組提供轉碼服務。

從以上細節層面可見,微服務模式相比整體式架構的好處顯而易見。如果確實是這樣的話——那為什麼這種模式最近才開始流行呢?

既然微服務好處多多,為什麼沒有很早就開始流行呢?

原因有二。第一個原因是它提升了我們的技術能力,另一個是最近的技術進步讓我們能夠把它帶到一個新的水平。

當我開始寫這個問題的答案時,發現一兩句話無法解釋清楚,所以實際上我把它分成了另外一篇文章,稍後再發表。因此在本文中,我將跳過從單個程序到多個程序的過程,忽略 ESBs 和面向服務的體系結構、組件設計以及有限的上下文等內容。

在很多方面我們已經開始使用微服務,隨著近期容器技術(特別是 Docker)和集群技術(如 Kubernetes、Mesos、Consul 等等)的普及,從技術的角度來看,微服務模式變得更加可行。

如果我們打算實施微服務,那麼在開始之前需要想清楚。從理論的角度我們看到了它的優點,那麼它有沒有弊端呢?

微服務有什麼問題?

微服務模式優點多多,那麼它的缺點是什麼呢?據我所知它主要有下列問題。

開發的複雜性增加

對於開發者來說事情會變得更加困難。當開發人員開發一個新功能時,如果該功能依賴其他服務的話,那麼開發人員不得不在他們的機器上運行所有服務,或者連接到這些服務。這通常比簡單地運行單個程序更加複雜。

這個問題可以通過一些工具得到部分緩解,但隨著構成系統的服務數量的增加,開發人員在整個系統運行時面臨的挑戰也越來越多。

運營的複雜性增加

對於維護服務的團隊來說,潛在的複雜性是一個巨大的挑戰。他們管理的服務不是簡單的幾個,而是數十、數百甚至數千個正在運行的服務。服務數量越多,通信鏈路就越多,那麼出錯的可能性就會變大。

devops 的複雜性增加

以上兩點表示開發和運營是分開進行的,隨著 devops 的普及(我是 devops 的忠實粉絲),devops 能夠緩解這個問題嗎?

如今有許多組織仍然依靠獨立的開發和運營團隊來工作,而也有一些組織更傾向於採用微服務。

對於已經採用了devops 的組織來說,這仍然很難。既是開發者又是運營者已經非常艱難(但是要建立好的軟體卻很關鍵)了,還得了解集群容器系統的細微差別,特別是快速發展的系統,那就更困難了。

它需要資深專家

如果開發團隊成員都是專家級別,那麼結果可能會很好。但想像一下,一個使用單一的整體式系統運行的不是很順暢。如果增加系統的數量,就會增加運行的複雜性。

通過有效的自動化、監控和集群等技術可以做到。但瓶頸很少在於技術本身,而在於找到能夠有效使用這些技術的人。目前這些技能需求非常高,可能很難找到。

真實世界的系統往往界限不清

當我們描述微服務的好處時,經常談到獨立的組件。但是在很多情況下,組件並不是獨立的。在論文中,某些領域可能看起來有限,但是當你深入細節時,你會發現他們比你預期的更具挑戰性。

事情變得非常複雜。如果你的界限沒有明確的定義,那麼即使理論上的服務可以單獨部署,你也會發現,由於服務之間的相互依存關係,你必須部署一組服務。

這意味著你需要一系列管理協同工作的服務版本,這些服務版本之間的協作需要通過驗證和測試,你實際上沒有可獨立部署的系統,為了部署新功能,你需要仔細編排並同時部署許多服務。

狀態的複雜性往往被忽略

在前面的例子中,我提到一個功能的部署可能需要同時部署多個版本的多個服務。假設合理的部署技術可以緩解這種情況,例如 blue/green 部署(大多數服務編排平台可輕鬆應對),或者並行運行的多個服務版本,以及決定使用哪個版本的通道。

如果服務是無狀態的,這些技術可以緩解大量的挑戰。但是無狀態服務非常容易處理。事實上,如果你有無狀態的服務,那麼我會傾向於考慮跳過微服務,而考慮使用無伺服器模型。

實際上,大多數服務都需要狀態。比如我們的視頻共享平台例子中的訂閱服務。新版的訂閱服務可以用新的形式將數據存儲在訂閱資料庫中。如果你並行運行兩個服務,則一次運行了兩個模式的系統。如果你進行了 blue green 部署,而其他服務依賴於新的數據,那麼必須同時更新這些服務,如果訂閱服務部署失敗並回滾,則需要層級回滾。

你可能會認為在 NoSQL 資料庫中這些問題不存在,但事實並非如此。不強制執行模式的資料庫並不意味著它是無模式系統 - 它僅僅意味著模式在應用級而不是資料庫級進行管理。理解數據的形狀及其演變過程的挑戰依然存在。

通信的複雜性往往被忽略

當你建立一個相互依賴的大型網路服務時,可能會涉及到很多服務間的通信,挑戰隨之而來。首先,潛在的失敗無處不在。假設網路調用失敗了,那麼當一個服務調用另一個服務失敗時,它至少應當重試幾次。服務之間的調用關係越多,那麼情況將變得愈加複雜。

假設用戶上傳視頻到共享服務中。那麼我們需要運行上傳服務,然後將數據傳遞到轉碼服務,此外,還得更新訂閱和推薦服務。所有這些調用都需要一定程度的協調,如果失敗,就得重試。

而重試邏輯可能很難管理。同步運行往往不是很穩定,很容易失敗。在這種情況下,更可靠的解決方案是使用非同步模式來處理通信。此處面臨的挑戰是非同步模式會使系統具有狀態性。如前所述,分散式系統和狀態系統很難處理。

當一個微服務系統使用消息隊列進行服務內通信時,基本上會有一個大的資料庫(消息隊列或代理)將這些服務粘合在一起。雖然起初看起來似乎沒什麼問題,但模式始終是一個隱患。新版本的服務可能會寫入新的格式的消息,當發送服務更改發送消息的詳細信息時,依賴於該消息的服務也需要更新。

當然可以擁有多個不同格式的消息處理服務,但數量一多就很難管理。當部署一個新版本的服務時,兩個不同版本的服務可能會處理來自同一隊列的消息,儘管消息來自不同版本的發送服務。這可能會導致複雜的邊緣情況。為了避免這些邊緣情況的產生,最好是只允許特定版本的消息存在,這意味著你需要將一組服務的版本作為一個整體來部署,以確保先前版本的消息被適當地排除。

這再次表明,當你深入細節時會發現獨立部署的想法可能與預期的有所差異。

版本控制變難

為了緩解前面提到的問題,我們需要謹慎管理版本。遵循像 semver 這樣的標準能夠解決這個問題嗎?答案是否定的。Semver 是一個利器,但是你仍然需要跟蹤協同工作的服務和 API 的版本。

這件事頗具挑戰,你可能自己都搞混,不知道哪個版本的服務可以一起正常工作。

在軟體系統中管理依賴關係是非常困難的,無論是節點模塊、Java 模塊、C 庫還是其他東西。獨立組件和單一整體之間的衝突很難處理。

當依賴關係是靜態,並且能夠進行修補、更新、編輯的時候,挑戰在所難免。但是如果依賴關係本身是實時服務,那麼你可能無法僅僅更新它們 - 你可能需要運行許多版本,或者直到整個系統得到修復。

分散式事務

在需要跨操作交易完整性的情況下,微服務可能會非常痛苦。分散式狀態很難處理,很多小的失敗單元可能會很難進行集群操作。

可以通過操作冪等性、重試機制等方法來避免這個問題,這些手段在許多情況下能夠起作用。但有些情況你需要保證操作的事務性,要麼成功,要麼失敗,而不能處於失敗和成功的中間狀態。在微服務模型中想要解決這個問題或者實現事務難度是很大的。

微服務可能是一種變相的整體式模型

單獨的服務和組件可以獨立部署,但是在大多數情況下,你將不得不運行某種集群平台,比如 Kubernetes。如果你使用谷歌的 GKE 或者亞馬遜的 EKS 這樣的託管服務,它們會幫你完成複雜的集群管理。

但是,如果你自己管理集群的話,那麼面對的是一個龐大而複雜的系統。雖然單個服務擁有前文提到的大量優點,但是你依然需要非常小心。這個系統的部署、更新、故障轉移等等操作起來都不是那麼簡單。

在大多數情況下,優點能夠得到體現,但是任然不要輕視或低估管理一個龐大而複雜的系統的難度。託管服務可能會有所幫助,但這些服務大都剛剛新起(例如,亞馬遜的 EKS 在2017年底才發布)。

微服務的狂熱將開始降溫

仔細考慮避免加入對微服務的狂熱追捧。為了幫助解決這個問題,我已經注意到了一些你可能想問自己的問題,並列舉了問題的答案:

2018 瘋狂微服務之死

點擊下載 PDF 版本:microservice-questions.pdf(https://github.com/dwmkerr/blog/raw/master/2018/microservice-madness/images/microservice-questions.pdf)。

不要把微服務和架構混淆

沒有微服務架構一說。微服務只是組件的另一種模式或實現。不論微服務是否在系統中使用,它都與架構無關。

微服務在許多方面與打包和操作的技術過程有關,而與系統設計無關。組件邊界仍然是工程系統中最重要的挑戰之一。

無論你的服務體量有多大,是否在 Docker 容器中,你都需要仔細考慮如何將系統放在一起。這裡沒有標準答案,只是多一個選擇而已。


原文:The Death of Microservice Madness in 2018

鏈接:http://www.dwmkerr.com/the-death-of-microservice-madness-in-2018/

作者:dwmkerr

譯者:安翔

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

工程師,你的錢究竟從哪來?

TAG:CSDN |