Medium的微服務架構解析

2021-02-07 21CTO

21CTO導讀:微服務架構的目標是幫助工程團隊更快,更安全,更高質量的交付產品,用來觸耦相關服務,從而讓團隊快速迭代,對系統的周邊部分影響很低。


在Medium,我們的技術棧始於2012年的單片Node.js應用程式。我們還創建了幾個衛星服務,但是我們還沒有制定一個系統採用微服務架構的策略。隨著系統越來越複雜,並且團隊不斷的開發,在2018年,我們轉向了微服務。


在本篇文章中,我們分享一下團隊有效實現並避免微服務「綜合症」的經驗。


何為微服務架構


首先,我們來思考微服務之架構是什麼,不是什麼。微服務是拯救那些過載和混亂軟體工程的技術趨勢之一。


在Medium團隊,我們認為它是:


「在微服務架構中,多個鬆散耦合的服務協同工作。每項服務都專注於一個目標,並具有較高的行業和數據之聚合力」。


微服務的設計包括以下三大原則:


1、單一性

每個服務應專注於一個目的並做好;

2、鬆耦合

服務彼此間沒有過多聯繫。對一項服務的修改不需要讓其它服務配合更改。服務之間的通信僅通過公共服務api進行。

3、高內聚

服務封裝了相關的行為和數據,如果我們需要構建一個新特性,所有的修改應該只涉及到一個服務。



微服務設計(建模)三原則


以下介紹微服務建模時,我們都應該遵守這三個設計原則。這是實現微服務架構全部潛力的唯一途徑,錯失任何一個都會成為反模式。


如果不是單一的目標,每個微服務慢慢就會做越來越多的事情,成長為多個「單片」服務。我們不會從微服務架構中獲得所有的好處,它會增加我們的運維成本。


如果沒有做到鬆耦合,對一項目服務的更改就會波及到其它服務,因此我們無法快速並安全的發布更新,這便是微服務架構的核心優勢。另外一個更重要的事情是,緊耦合引發的問題將是災難性的,比如數據不一致,甚至導致數據丟失。


如果沒有高內聚,我們最終還是會得到一個分布式的單片系統,那是一組混亂的服務,必須同時修改和部署才能構建單一功能。由於多個服務協調的複雜性和成本很高,有時要跨多個團隊協調,分布式單片系統通常比集中式單片系統的性能差很多。


微服務其實也並非那麼重要,有如下原因:


1、微服務並不是小數量的代碼行或者「微小」任務的服務。這種誤解來自於「微服務」這個名字。微服務架構的目標並不是讓團隊有儘可能多的小型服務。只要符合上述三項原則,服務就有可能複雜的。


2、一個微服務不是被新技術所組成的服務。儘管微服務架構允許團隊更輕鬆地測試新興技術,但這並不是微服務的主要目標。只要團隊從分離的服務中受益,你就可以使用相同的技術棧構建新服務。


3、微服務並非必須從頭創建服務。如果你已經有一個架構優良的單片應用程式,那麼不用從頭一個個的來構建新服務。可能的策略是,直接從單一服務中提取邏輯。這樣,上面提到的三個原則仍然有效。


Medium 的微服務策略
1、構建具有明確價值的新服務


一定不要為了構建而去構建新服務,每次我們構建一個新服務時,必須具有明確的產品或者工程價值。


產品價值表現在能給用戶帶來好處,工程價值表現在可以使技術團隊的工作更好、更快,只有價值優於在 Node.js 單片應用中構建時才決定構建新的服務,否則就繼續Nnode.js單片應用中修改。


2、單體持久化存儲是有害的


持久化存儲建模在微服務建模中是一個重要部分,服務間共享持久化存儲實現非常簡單的方式,但危害極大,我們要儘量避免。


持久化存儲涉及到產品實現細節,服務間共享數據存儲就把一個服務的實現細節暴露給了整個系統,如果這個服務修改了數據格式、添加了一個緩存層,其他服務就要跟著做相應的修改,這樣嚴重違背了鬆耦合原則。


如果共享了數據持久化存儲,那麼例如數據的修改、使用等行為就需要多個服務都各自實現,這違背了高內聚原則。如果修改某個行為,其它相關服務都要跟著修改。


在微服務架構中,一個特定類型的數據應該只由一個服務負責,其他服務應該通過API來調用此服務請求數據,或者僅僅是持有數據的只讀副本。


以下我們來看一個實際的例子,比如要構建一個新的個性化推薦服務,需要 Post 表中的數據。


單片的持久化存儲方式:

在單片架構中,個性化推薦服務直接訪問 Post 表,缺點如下:

緩存會變得很棘手,如果推薦服務共享了單體應用的Cache,我們就必須在推薦服務中實現Cache的細節,如果推薦服務使用自己的Cache,當單體應用更新了Post數據時,我們不知道什麼時候使Cache中的數據失效。

如果單體應用決定更換資料庫,例如從DynamoDB換成RDS,那麼就需要重新實現推薦服務中的相關邏輯。

在單體應用中,Post數據涉及到複雜的邏輯,例如如何決定一個Post是否呈現給某個用戶,在個性化推薦服務中就也需要實現這些邏輯。如果單體應用中添加或者修改了邏輯,那麼推薦服務也得跟著變化。

單片服務使用了DynamoDB,那麼推薦服務也就被限制在了這個資料庫,即使這個資料庫並不適合此服務。


在解耦的微服務模式中,推薦服務不再直接訪問Post數據,單片服務負責Post實現細節,而且有多種方案可選。


方案A,由一個 post service 擁有 post 數據,其它服務通過它的API來訪問post數據表。

方案B,當post數據發生更新時,單片服務通過消息隊列服務通知給個性化推薦服務。

方案C,由ETL管道為推薦服務產生post數據的只讀副本。

這3個方案中,個性化推薦服務都可以完全的擁有自己的數據,所以可以靈活的應用,例如Cache的實現、選擇適合自己的資料庫等等。


3、服務只關注自己的業務邏輯


每個服務應該只關注它自己的工作,最好不要管別的複雜的亂事,比如網絡、通信協議、部署、監控等等,服務管理相關工作應該與服務實現完全解耦。


1)網絡


網絡通信(服務發現、路由、負載均衡、流量等)是運行服務的重要部分,傳統方法是提供公眾語言庫,但是不夠理想,因為應用需要做全部的集成工作和維護工作。


現代化的解決方案是使用 Service Mesh,Medium 使用了 Istio 和 Envoy,構建服務的工程師完全不用關心網絡相關的工作。


2)通信協議


不管你選擇什麼技術棧或語言來構建微服務,選擇一個好的RPC方案是極其重要的,RPC方案需要高效、跨平臺、較小的開發量,Medium 選擇的 gRPC(https://grpc.io)。


目前基於 HTTP 的 REST+JSON 方案非常普遍的。但在 Server-to-Server 的通信的效率卻不是很高,尤其是需要發送大量請求的情況下,而且沒有自動生成的樣本代碼,我們需要手動實現伺服器/客戶端代碼。


3)部署


使用一致的方法來構建、測試、打包、部署、管理所有的服務是非常重要的,Medium 的所有微服務都運行在容器中,使用 Kubernetes 編排管理。

Medium 開發了自己的一套系統,來構建、測試、打包、部署服務,每個服務只需要提供基礎信息,例如監聽埠、build/test/start 命令等,其他事情都由系統來處理。


4、徹底而一致的監控


監控可以讓我們知道系統正在如何工作,當出現問題後可以方便地追蹤問題。監控行為包括日誌、性能指標、儀錶盤、報警等。


Medium 剛開始轉到微服務時,遇到了兩個問題:


第一,由於微服務複雜度高,很難監控,導致系統沒有可監控性。

第二,不同團隊對於自己那塊兒做監控,重複創造輪子,最終導致監控碎片化,碎片化數據很難連接、歸類,可監控性極低。


後來 Medium 使用了 DataDog 服務,實現了自動化儀錶盤、告警、日誌,還使用了 LightStep 來跟蹤系統性能。


5、從開始就避免使用微服務綜合症


微服務不是靈丹妙藥,它能解決一些問題,但同時也創造了一些其它問題,我們將其稱為「 微服務綜合症 」。


如果從一開始不去考慮,那麼這些事情會變得越來越糟糕,如果我們以後再照顧它們會花費更多成本和時間。


以下是一些常見的大症狀,供大家參照:


1、設計不良的微服務造成的傷害大於好處,特別是當你有超過幾個微服務時。

2、允許太多不同的開發語言/技術棧並存,這會增加運維成本,使開發組織分散。

3、將運行服務與構建服務混合在一起,這增加了每項服務的複雜性並減慢了團隊的開發速度。

4、忽略資料庫設計,最終得到只是單一數據存儲的微服務。

5、缺乏可視性,對性能問題或故障難以進行分類。

6、當遇到問題時,團隊傾向於創建新的輪子而不是修復現有服務,即便後者是最好選擇。

7、即使服務是鬆耦合,但是缺乏整個系統的整體畫像也存在極大問題。


6、尊重失敗



技術團隊要經常思考如何做失敗測試、如何很好的解決錯誤。


首要一點是隨時要有面臨出錯的意識。

對於 RPC接口,要在處理錯誤上多做工作。

對於失敗要可監控。

上線新服務時要多做失敗檢測,整理出檢查清單。

構建自動恢復機制。


7、我們應該停止構建單片應用?


伴隨著技術的不斷創新,構建微服務架構變得容易得多。這是否意味著都應該停止構建單片架構與服務?


雖然新技術支持變好,但微服務仍然是高度複雜性和高複雜的架構。


對於小型團隊來說,單一的應用程式通常仍然是更好的選擇。


但是,開始時要創建一種系統化和有成長的預見力,在以後能更容易遷移到微服務架構的單片應用架構。


單片體系結構須確保模塊化,應用上述三個微服務原則(單一性,鬆耦合和高內聚)來構建,除了「服務」外,使用同一技術棧來實現,部署在一起並在同一個容器中運行。


Medium在早期應用中得益於一些較好決策,首先組件高度模塊化,後來即使發展成為一些複雜的應用,包括Web服務,後端服務和離線事件處理、脫機事件處理等,但它們都用完全相同的代碼,這使得業務邏輯很容易抽象為單獨服務,只要新服務提供與原始模板實現相同的API即可。


整體應用封裝了數據存儲層,每種數據類型(例如,資料庫表)都具有兩層實現:數據層與服務層。


所有CRUD操作都由一個數據服務層處理,它封裝了一個特定類型的數據的高級邏輯,並提供公共API。


微服務彼此不共享數據存儲,數據實現細節完全隱藏在代碼的其它部分,這樣創建新服務與處理數據容易也更安全。


單片應用還可以幫我們專注於系統最重要部分,不用從頭開始做微服務設計。


小結


單片的Node.js應用伴隨Medium正常運行了好幾年,隨著項目的複雜度越來越高以及產品快速迭代,技術棧開始系統地採用微服務架構。


即便如此,技術團隊仍然處於這一過程的早期階段,但我們已經看到了微服務的優勢與潛力,它大大提高開發效率,讓人們能夠更大膽思考提升產品,解放軟體工程團隊能夠安全的測試、開發新技術。



編譯:洛逸

來源:Medium技術團隊

地址:https://medium.engineering/microservice-architecture-at-medium-9c33805eb74f


相關焦點

  • Medium 的微服務架構
    我們已經建立了幾個附屬服務,但我們還沒有制定採用微服架構系統的戰略。隨著系統變得更加複雜和團隊的壯大,我們在 2018年初遷移到了微服務架構。在這篇文章中,我們希望分享我們的經驗,有效地做到這一點,避免微服務症候群。微服務架構是什麼?
  • 全面解析Netflix的微服務架構設計
    Netflix 意識到,它需要一個沒有單點故障的更可靠的基礎架構。因此它做出兩個重要決定:將 IT 基礎架構從自己的數據中心遷移到公共雲上,並通過微服務架構,用較小的易管理軟體組件替換單體程序。這兩個決定為今天 Netflix 的成功打下了堅實基礎。
  • 全面解析 Netflix 的微服務架構設計
    Netflix 意識到,它需要一個沒有單點故障的更可靠的基礎架構。因此它做出兩個重要決定:將 IT 基礎架構從自己的數據中心遷移到公共雲上,並通過微服務架構,用較小的易管理軟體組件替換單體程序。這兩個決定為今天 Netflix 的成功打下了堅實基礎。
  • Medium 架構實踐:避免微服務綜合症
    微服務架構的目標是幫助工程師團隊更快、更安全、更高質量地交付產品。解耦服務使團隊能夠快速迭代,並儘可能降低對系統其餘部分的影響。在 Medium,我們的技術棧始於 2012 年的單體 Node.js 應用程式。我們已經構建了幾個衛星通訊服務,但還沒有系統地制定一個採用微服務架構的策略。隨著系統變得越來越複雜並且團隊不斷發展,我們在 2018 年初轉向了微服務架構。
  • 下一代的微服務架構基礎是ServiceMesh?
    今年,ServiceMesh(服務網格) 概念在社區裡頭非常火,有人提出 2018 年是 ServiceMesh 年,還有人提出 ServiceMesh 是下一代的微服務架構基礎。作為架構師,如果你現在還不了解 ServiceMesh 的話,是否感覺有點落伍了?那麼到底什麼是 ServiceMesh?它的誕生是為了解決什麼問題?
  • 10個微服務架構設計的最佳實踐
    微服務極大改變了服務端引擎的架構方式。微服務不是一個單一的巨型的用來託管應用程式所有業務邏輯的代碼庫,而是反映了分布式系統模型,在該模型中,一組應用程式組件協同工作來滿足業務需求。通過遵循十項基本的微服務最佳實踐,你可以實現一個高效的微服務生態系統,從而避免不必要的架構複雜性。
  • 微服務架構與服務網格Service Mesh
    微服務架構提到微服務,想必每個人都耳熟能詳,多少都能說上兩句。的演講,這是最早版本的微服務的定義。在這之後。在2014年三月,Martin Fowler的這篇文章《Microservices》通俗易懂的講解了什麼是微服務架構。文章中提到: 微服務是一種軟體架構風格,它是以專注於單一責任與功能的小型功能區塊 為基礎,利用模塊化的方式組合出複雜的大型應用程式,各功能區塊使用與語言無關的 API 集相互通信。
  • DaoCloud 主辦首屆全球微服務架構高峰論壇,引領微服務發展浪潮
    DaoCloud 此次舉辦首屆全球微服務架構高峰論壇,攜手世界級微服務專家,旨在匯聚微服務領域的精英人才共同探討微服務發展的未來,引領全球微服務發展浪潮。DaoCloud 主辦本次會議不以「盈利」為目標,致力於為技術從業者舉辦一場最純粹的技術盛會。本次大會的門票收入將捐獻給 Golang 中國開源基金會。
  • 淺談微服務架構設計
    這樣才不會錯過每日進階架構文章呀。架構定義是一門技術,但更是一門藝術。微服務架構是基於分而治之的思想演化出來的。過去傳統的一個大型而又全面的系統,隨著網際網路的發展已經很難滿足市場對技術的需求,於是我們從單獨架構發展到分布式架構。
  • 微服務架構設計(一):核心概念&從既有的架構遷移到微服務的策略
    所謂的微服務具體應包含哪些核心的概念?既有的架構遷移到微服務的又有哪些策略?微服務設計是架構設計。所以, 微服務設計不應是一個講求標準答案, 簡單粗暴的設計過程。而應該是一個考量各方因素下的一個決策的過程。所以, 在探討微服務設計前, 我們先來探討下, 所謂的微服務具體應包含哪些核心的概念?
  • 微服務架構雲端應用
    話題:微服務架構雲端應用講師:劉凡職位:好雨雲創始人兼CEO簡介:曾任澳客網 CTO和CEO職位。擁有超過12年網際網路產品開發和管理經驗,專注於網際網路技術架構設計,對產品設計、敏捷開發、安全、OKRs、大數據等領域有深入研究。現推崇反應式編程(http://www.reactivemanifesto.org/),並在多個產品中成功應用。劉總在這次分享中主要為大家介紹了什麼是徽服務,實現微服務有哪些架構模式以及微服務在實際中的應用情況。
  • 組件化、模塊化、集中式、分布式、服務化、面向服務的架構、微服務架構
    面向服務架構,從語義上說,它與面向過程、面向對象、面向組件一樣,是一種軟體組建及開發的方式。與以往的軟體開發、架構模式一樣,SOA只是一種體系、一種思想,而不是某種具體的軟體產品。(微觀SOA:服務設計原則及其實踐方式(上篇))微服務架構微服務架構(MicroService)是一種服務化架構風格,通過將功能分散到各個離散的服務中以實現對解決方案的解耦。微服務架構強調的第一個重點就是業務系統需要徹底的組件化和服務化(這也是我們為什麼要先介紹組件化和服務化的原因)。微服務的誕生並非偶然。
  • DDD到底適不適合微服務架構?
    從初期的單體架構,到豎井式架構、RPC架構,再到大放異彩的微服務架構,可以說架構演進,本質上就是基於業務,對現有架構的抽象過程。一名架構師,最怕缺少全局意識和長線思維。如果架構師設計架構的出發點,只是緩解燃眉之急,那麼在未來,這套系統的迭代會越來越困難,很可能陷入推翻、重建,再推翻、再重建的「鬼打牆」。
  • 微服務架構-從理想到現實
    ,而是結合我們自己所做的一些微服務架構實踐情況做一些總結和復盤。架構的核心思維仍然是:分解+集成但是傳統架構在分解的時候沒有做到單個組件的高度獨立自治和徹底解構。這個高度獨立自治實際上要求組件或模塊從開發,設計,測試,上線運行,後期運維全生命周期都做到高度獨立;同時還要求配合的開發團隊,組織結構設計也獨立。也正是這個原因進一步發展出了微服務架構。
  • 微服務架構中配置中心的選擇,Apollo值得擁有
    目前公司內部微服務架構基礎設施建設中,技術選型以Spring Cloud技術為主,也被大家俗稱作「全家桶」。Spring Cloud Config配置中心介紹&架構在微服務架構體系中配置中心是比較重要的組件之一,Spring Cloud官方自身提供了Spring Cloud Config分布式配置中心,由它來提供集中化的外部配置支持,它分為客戶端和服務端兩個部分。
  • 一文看懂Java微服務架構,WEB2.0,垂直架構,分布式架構,微服務架構
    Java微服務架構目錄:了解開發環境&生成環境WEB1.0 & WEB2.0垂直架構
  • 微服務架構談系列(2):微服務到底是什麼鬼?
    傳統上,架構的目標是可擴展性、可靠性和安全性。但是今天,該架構能夠快速安全地交付軟體,這一點非常重要。你將了解微服務架構是一種架構風格,可為應用程式提供更高的可維護性、可測試性和可部署性。我將通過描述軟體架構的概念及其重要性來開始本文。接下來,我將討論架構風格的概念。然後我將微服務架構定義為特定的架構風格。讓我們從理解軟體架構的概念開始。
  • 【雲計算】微服務架構設計 (一): 核心概念 & 從既有的架構遷移到微服務的策略
    微服務設計是架構設計。所以, 微服務設計不應是一個講求標準答案, 簡單粗暴的設計過程。
  • 微服務架構~Zuul1.0和2.0我們該如何選擇?
    上圖是Zuul2的架構,和Zuul1沒有本質區別,兩點變化:前端用Netty Server代替Servlet,目的是支持前端異步。波波和極客時間合作的課程《微服務架構和實踐160講》,7月份馬上上線第三模塊《微服務網關Zuul架構和實踐》,其中會講解Zuul1如何使用AsyncServlet優化連接數,歡迎大家關注。對於Zuul2,我的建議是持謹慎觀望的態度,可以在測試環境小規模實驗驗證,但是暫不上到生產環境。
  • 一文詳解微服務架構
    本文將介紹微服務架構和相關的組件,介紹他們是什麼以及為什麼要使用微服務架構和這些組件。本文側重於簡明地表達微服務架構的全局圖景,因此不會涉及具體如何使用組件等細節。要理解微服務,首先要先理解不是微服務的那些組件概念。