從單體到微服務再合併,我們找到了平衡點

雲棲號資訊:【點擊查看更多行業資訊
在這裏您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

有人說,程序員總是對好的東西如數家珍,對不好的東西置若罔聞。2015 年,當微服務炒作開始飛起,每個人都在議論它的好處:

  • 彈性;
  • 伸縮性;
  • 易於部署;
  • 清晰的邊界。

我們公司也從單體轉向了微服務,但最後在二者之間找到了一個平衡點。微服務的一些好處是切實存在的,但它的一些缺點和潛在風險也不可忽視。

從單體到微服務

我於 2017 年加入公司,當時我們的團隊大約有 20 名工程師,我們的應用程序是一個部署在 ECS 上的 Django 單體。

在過去兩年裏,我們開發了很多新服務,以下是一個不完整的清單:

  • 票據服務:管理客戶票據;
  • 收費服務:管理 Stripe 的收費和支付;
  • 定價服務:管理服務定價;
  • 匹配服務:爲企業經理和供應商之間牽線搭橋;
  • 消息服務:管理聊天功能;
  • 通知服務:管理推送通知、應用內通知和郵件;
  • 審覈服務:供應商審覈客戶;
  • Netsuite 同步服務:將數據同步到 Netsuite;
  • Salesforce 同步服務:將數據同步到 Salesforce;
  • Stripe 同步服務:Stripe 和我們的系統之間的一個傳輸層;
  • RDS 監控服務:確保我們的 Postgres 數據庫正確備份;
  • Datadog 監控服務:監控 Datadog 代理運行正常;
  • GitHub 通知服務:在接到 PR 代碼評審時可以收到 Slack 通知;
  • Gadgets:工具套件。

看着服務數量增長是一件令人感覺良好的事情。畢竟,我們趕上了現代化開發實踐的步伐!除此之外,相比單體,開發這些小型服務讓我們感覺更好。

收割微服務的好處

微服務確實有顯而易見的優勢。

清晰的邊界

微服務提供了清晰的服務邊界。哪些東西應該由誰負責,幾乎沒有留下模棱兩可的餘地。如果你的團隊擁有某個服務,那麼與這個服務相關的問題就應該由你的團隊負責解決。清晰的邊界讓團隊專注於自己的服務,不會讓問題惡化。

更小的測試集

我們的單體需要 5 到 10 分鐘才能跑完測試,而微服務只需要幾秒鐘。

更快的部署

更小的測試集帶來了更快的部署速度。我們的單體有一些基於 Selenium 的測試,用於確保儀表盤關鍵功能運行正常。但有很多服務不是面向用戶的,完全可以跳過這些測試,直接把這些服務的部署時間降低了一半。

CI/CD 問題的影響範圍更小了

有時候,某個服務的 CI/CD 管道出了問題會影響到其他新代碼的部署或者會導致 bug 被髮布到生產環境,我們不得不暫停部署,一直等到問題被修復。在開發單體時,所有開發人員的 PR 都必須暫停,等問題得到修復。但是,如果是開發微服務,其他團隊的問題不會影響到你的部署。所以,微服務最令人感到幸福的一點是部署速度快。

更簡單更低的依賴風險

如果只是對某個服務做出變更,在做出變更時就不會那麼可怕了。所以,相比單體,我們的很多微服務都可以保持最新狀態。例如,當我們的微服務更新到 Python 3 時,單體仍然在使用 Python 2。很多團隊不敢隨意更新單體,因爲那樣可能會影響到系統的其他部分,而他們對這些部分不太熟悉。另外,更新單體的責任應該由誰來擔?這個很難說清楚。

微服務的缺點

隨着微服務數量的增長,我們開始感到事情不像之前那麼順利了。

需要維護更多的基礎設施

每多一個新服務,就會增加一些基礎設施。比如,一個 ECS 服務、一個 Postgres 實例或一個 RabbitMQ 實例。CI/CD 的配置也會增加,還需要進行第三方服務(比如 Rollbar/Sentry)配置。依賴也需要更新,而且需要更新依賴的地方越來越多。基礎設施團隊在項目上花了很多時間,爲每一個服務重複着枯燥無味的工作。

無人照看的服務

小型的服務容易被人忽略,在運行起來之後,基本上會被擱在一邊,最後就會過時。

一個微服務如果半年沒有被動過,人們一般就不太會去修改它,其中有 90% 的修改都是依賴更新或基礎設施更新。也就是說,我們給自己增加了額外的維護負擔。

更慢的功能開發

如果服務邊界沒有搞清楚,會顯著降低功能的開發速度,這是微服務的一個很大的風險點。開發一個跨多個服務的功能需要做更多的工作,而重構一個跨多個服務的功能是一個噩夢。如果服務邊界很清晰,大部分項目只會影響到一個服務。但是,對於初創公司來說,它們的發展方向是不可預測的。一個產品的兩個部分在一開始可能是完全獨立的,但一年之後可能會變得緊密耦合起來。所以,要完全清晰地定義服務邊界不是件容易的事。

依賴庫

爲了讓所有微服務使用同級的依賴,我們需要從單體拉取依賴庫,而更新這些依賴庫成了我們的一個痛點。更新依賴庫需要發佈新版本,如果庫很重要,需要在很多地方做出更新。

技術大雜燴

微服務帶來的一個好處是“技術多樣性”,但它最後會變成一個問題。我們的單體是用 Django 開發的,而我們的部分微服務使用了 Flask。單體使用 Celery 處理異步任務,而部分微服務使用了 RabbitMQ。有一個微服務使用了 DynamoDB,而其他微服務使用了 Postgres。

後來,我們花了很多時間重構微服務,讓所有的微服務都用上同樣的技術。因爲一些庫依賴了某些特定的技術,而我們的一些微服務無法使用它們。另外,技術多樣性會給新加入的開發人員增加難度。

本地開發問題

隨着微服務數量的增多,在開發時就需要在本地運行更多的服務。應用程序的容器化確實幫了我們一些忙,但相比之前,我們不可避免地遇到了更多本地開發問題。

找到平衡點:合理大小的服務

在轉向微服務兩年之後,我們開始合併微服務。一些微服務被合到了單體中,其他的則合併成較大的服務。在一年中我們總共移除了 9 個微服務。

當然,並不是說我們所有的微服務都是失敗的。例如,我們的票據服務與計費及其他幾個服務合在一起,有着清晰而穩定的邊界。有四個微服務被合併到了“Gadgets”服務中,而這個服務成了與核心領域模型無關的工具的聚集地。

大小合理的服務承擔着相當大的責任,大多數功能開發都可以在單個服務中完成。它們足夠大,不會給我們增加太多的基礎設施維護負擔。服務邊界清晰,避免團隊在開發過程中彼此影響。

如果你的公司正在考慮遷移到微服務架構,那麼要注意劃分服務邊界,並考慮使用大小合理的服務。

【雲棲號在線課堂】每天都有產品技術專家分享!
課程地址:https://yqh.aliyun.com/live

立即加入社羣,與專家面對面,及時瞭解課程最新動態!
【雲棲號在線課堂 社羣】https://c.tb.cn/F3.Z8gvnK

原文發佈時間:2020-06-23
本文作者:Per-Andre Strømhaug
本文來自:“infoq”,瞭解相關信息可以關注“infoq

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章