一起玩轉微服務(1)——概念

skyme發表於2020-06-15

一、什麼是微服務

隨著各行各業公司的快速發展,業務規模的不斷擴大,不可避免的造成原有架構不能夠適應快速的增長和變化。這時,微服務就進入大家的視野,其實在微服務之前,很多的公司已經做過服務化的改造,並且取得了一定的成果,但是對於整體流程的標準化還有一定有差距。那麼,什麼是微服務呢?
準確的說,微服務是一種軟體架構模式,將大型系統或者複雜的應用分割成多個服務的架構,服務之間互相協調、互相配合,為使用者提供最終價值。每個服務都有獨立的生命週期,可以單獨的維護和部署,各個業務模組之間是鬆耦合的,比傳統的應用程式更有效地利用計算資源,應用的擴充套件更加靈活,能夠通過擴充套件元件來處理功能瓶頸問題。這樣一來,開發人員只需要為額外的元件部署計算資源,而不需要部署一個完整的應用程式的全新迭代。
一個微服務的架構如圖所示,單體應用被拆分成多個微小的服務:

也有人將微服務的開發比喻成搭積木,每個服務都是一個零件,使用這些不同的服務可以搭建出不同的形狀。簡單的說,微服務架構就是把一個大系統按業務功能分解成多個職責單一的小系統,並利用簡單的方法使多個小系統相互協作,組合成一個大系統。
其實這裡蘊含著自古以來的真理,就是分而治之,當一件事情大到不能處理的時候,就使用一定的切分方法,將其變成很多微小的類,然後分門別類的進行處理,以達到最好的效果,最終實現1+1>2的功效。
微服務的優點和缺點(或者說挑戰)一樣明顯。
優點

  • 開發簡單,每個服務完成獨立的功能

  • 技術棧靈活,可以選擇不同的語言完成不同的服務,發揮各種語言的最大優勢

  • 服務獨立無依賴,每個服務都可以單獨部署,一個服務出現問題不會導致整個系統癱瘓

  • 獨立按需擴充套件,以應對高併發以及大流量

  • 可用性高,當其中一個點出現問題時,能夠及時切換,不影響業務正常執行

  • 複雜應用解耦為小而眾的服務,拆分可以基於一定的原則,將耗時的應用解耦

  • 各服務精而專,也就是我們常說的專人幹專事,對映到微服務中就是專服務幹專事

  • 服務間通訊通過API完成,選擇輕量的API通訊

    缺點(挑戰)

  • 多服務運維難度,服務的增加意味著運維的困難,如何有效的管理是一個挑戰

  • 系統部署依賴,當業務複雜是,系統之間的耦合關係高度耦合,如何高效部署是一個挑戰

  • 服務間通訊成本,包括網路延遲,介面不可用性等,保證服務的高可用性是一個挑戰

  • 資料一致性,再各個服務間如何有效的共享資料,確保相應服務的資料需求一致性是一個挑戰

  • 系統整合測試,拆分後,原本需要測試的內容成倍的增加,如何高效的降低測試成本是一個挑戰

  • 重複工作,服務拆分之後,由於資訊的不對稱導致的重複性工作,如何有效抽象是一個挑戰

  • 效能監控,原本只需要一個監控的部分,現在需要分開監控,如何快速定位問題是一個挑戰

  • 溝通成本的成倍增加,服務拆分後,各個服務由單獨的人來維護,如何高效的溝通是一個挑戰

二、為什麼微服務

從一般的平臺遇到的問題說起,平臺的問題包括:

  • 服務配置複雜。基礎服務多,服務的資源配置複雜。傳統方式管理服務複雜。
  • 服務之間呼叫複雜。檢索服務、使用者中心服務等,服務之間的呼叫複雜,依賴多。
  • 服務監控難度大。服務比較多,機器部署複雜,服務存活監控、業務是否正常監控尤為重要。
  • 服務化測試問題。服務依賴性比較大,測試一個小的功能,周邊服務也需要啟動。

那麼微服務的架構有什麼優勢,大家為什麼都懷著極高的熱情來應對微服務呢。

1. 區別

首先看一下兩者的區別,單體應用和分散式應用都有哪些優點和缺點呢,通過下面的表格來做一下分析和對比?

 

 

從上面的表格我們可以看到,分散式系統雖然有一些優勢,但也存在一些問題。

  • 架構設計變得複雜(尤其是其中的分散式事務)。
  • 部署單個服務會比較快,但是如果一次部署需要多個服務,部署會變得複雜。
  • 系統的吞吐量會變大,但是響應時間會變長。
  • 運維複雜度會因為服務變多而變得很複雜。
  • 架構複雜導致學習曲線變大。
  • 測試和查錯的複雜度增大。
  • 技術可以很多樣,這會帶來維護和運維的複雜度。
  • 管理分散式系統中的服務和排程變得困難和複雜。

也就是說,分散式系統架構的難點在於系統設計,以及管理和運維。

接下來我們就一起來看一下架構的演變過程。

2. 從單體應用說起

下圖是我們非常熟悉的單體應用,或者說是非常傳統的應用架構。
從圖中可以看到,應用通過瀏覽器進行訪問,當訪問到訂單服務的時候,分單服務提供相應的功能,然後去訪問應用的資料層,資料層負責對資料的解析,這是一個極其典型的單體應用結構,這種結構所帶來的問題顯而易見,資料庫存在單點,所有服務都耦合在一個應用中,當其中一個服務出現問題的時候,整個工程都需要重新發布,從而導致整體業務不能提供響應。這種結構在小專案中是沒有什麼問題的,而且操作起來非常靈活,但當業務量爆增的時候,就無法靈活應對了。

 

 

3. 第一步切分

為了應對單體應對無法滿足業務增漲,需要對資料庫進行進一步的切分,以提高擴充套件性,下圖就是一個切分後的架構圖。

業務之間通過程式間的服務進行相互呼叫,資料庫之間沒有耦合性,不會存在單點故障。前端只需要呼叫相應的服務,返回自身需要的資料,然後與使用者進行互動。可以看到,這種方式比傳統的單體應用已經前進了一步,但是資料庫層面仍然存在著問題,根據資料量需要評估是否使用讀寫分離的設計,服務層面也增加了相應的複雜性。前端呼叫隨著呼叫介面數量的增加也急需治理。

4. 服務化所帶來的問題

隨著服務的拆分,新的問題應運而生。客戶端如何訪問這些服務?這些服務的呼叫情況,切分是否合理,安全問題,如果受到攻擊應該如何應對,是否可以使用限流或者降級的方式來及時解決。
應對這些問題,API閘道器是一個不錯的解決方案。當有新的裝置需要呼叫這些介面時,可以複用原有介面,不需要進行二次開發。介面的維護也會更有條理性,對於訪問次數,安全等問題,都可以在這一層進行解決。

解決了應用前端訪問的問題後,服務之間的相互呼叫也是一個問題,如果整個系統內部呼叫關係混亂,就會帶來非常多的不必要的問題。所以約定好服務之間的通訊方式是非常有必要的。不管是開源還是公司內部研發,都有非常多的解決方案。最簡單的方式,是通過rpc的呼叫,傳輸json或者XML,雙方定義好協議格式,通過報文的方式進行資料傳輸。
當多種服務需要互相呼叫的時候,服務的數量會急劇的增加。服務的治理就成為新的問題。不同的服務的版本問題。如果不能通過一個單獨的註冊地址,像書的目錄一樣來管理整個服務結構,服務的呼叫就侍顯示非常混亂。
一般的分散式服務,都有一個註冊中心,例如dubbo是基於zookeeper進行的二次開發,自身提供管理控制檯,可以對服務進行註冊和查詢,Spring Cloud有Eureka,還有etcd,consul等可供選擇。
經過上面的處理,整體上來看應用已經達到了一個非常好的狀態,但是每個應用服務仍然存在著單點問題,當一個服務出現問題的時候,有可能導致連鎖的反應,使用整個系統癱瘓。這時候需要除了監控告警之外的一種容錯機制保障整體服務的可執行性。
通過閘道器層的反向代理來實現高可用是一個不錯的解決方案,訪問層無需要了解整個體系有多少應用提供,只需要關心服務是否能夠提供服務,並且對必要的介面進行監測,當發現介面無法正常提供服務時,提供相應的告警機制,以微信、簡訊或者郵件的方式通知相關人及時進行處理。
隨著服務的切分,業務的擴充套件,資料量的激增也是一個非常大的問題,如果採用傳統的方案來應對,各種關係型資料庫都有瓶頸,把運算量比較大,比較耗資源的運算,跨庫統計查詢的需求。
再下一步隨著資料量的不斷增漲,需要業務和統計分離。
統計一般都是比較耗時的應用,比如計算使用者的留存情況,需要分析一週甚至是更長週期內的使用者資料,如果使用線上的方式分析顯然不太現實,所以,對於大資料量的分析和資料探勘,需要從業務中抽取資料進行離線分析,然後將分析的結果進行展現。

5. 微服務的可擴充套件性

針對以上的分析,可以看到,微服務需要具備極強的可擴充套件性,這些擴充套件性包含以下幾個方面:
• 效能可擴充套件:效能無法完全實現線性擴充套件,但要儘量使用具有併發性和非同步性的元件。具備完成通知功能的工作佇列要優於同步連線到資料庫。
• 可用性可擴充套件:CAP理論表明,分散式系統無法同時提供一致性、可用性和分割槽容錯性保證。許多大規模Web應用程式都為了可用性和分割槽容錯性而犧牲了強一致性,而後者則有賴於最終一致性來保證。
• 維護可擴充套件:軟體和伺服器都需要維護。在使用平臺的工具監控和更新應用程式時,要儘可能地自動化。
• 成本可擴充套件:總成本包括開發、維護和運營支出。在設計一個系統時,要在重用現有元件和完全新開發元件之間進行權衡。現有元件很少能完全滿足需求,但修改現有元件的成本還是可能低於開發一個完全不同的方案。另外,使用符合行業標準的技術使組織更容易聘到專家,而釋出獨有的開源方案則可能幫助組織從社群中挖掘人才。

6. 微服務與SOA的區別

面向服務的架構(SOA)是一個元件模型,它將應用程式的不同功能單元(稱為服務)通過這些服務之間定義良好的介面和契約聯絡起來。介面是採用中立的方式進行定義的,它應該獨立於實現服務的硬體平臺、作業系統和程式語言。這使得構建在各種各樣的系統中的服務可以以一種統一和通用的方式進行互動。
都是做服務化,那麼微服務與SOA的異同有哪些呢?
相同點:

  • 需要Registry,實現動態的服務註冊發現機制;
  • 需要考慮分散式下面的事務一致性,CAP原則下,兩段式提交不能保證效能,事務補償機制需要考慮;
  • 同步呼叫還是非同步訊息傳遞,如何保證訊息可靠性?SOA由ESB來整合所有的訊息;
  • 都需要統一的Gateway來匯聚、編排介面,實現統一認證機制,對外提供APP使用的RESTful介面;
  • 同樣的要關注如何再分散式下定位系統問題,如何做日誌跟蹤,就像我們電信領域做了十幾年的信令跟蹤的功能;

差異點:

  • 是持續整合、持續部署?對於CI、CD(持續整合、持續部署),這本身和敏捷、DevOps是交織在一起的,所以這更傾向於軟體工程的領域而不是微服務技術本身;
  • 使用不同的通訊協議是不是區別?微服務的標杆通訊協議是RESTful,而傳統的SOA一般是SOAP,不過目前來說採用輕量級的RPC框架Dubbo、Thrift、gRPC非常多,在Spring Cloud中也有Feign框架將標準RESTful轉為程式碼的API這種仿RPC的行為,這些通訊協議不應該是區分微服務架構和SOA的核心差別;
  • 是流行的基於容器框架還是虛擬機器為主?Docker和虛擬機器還是物理機都是架構實現的一種方式,不是核心區別;

SOA和微服務的一個主要不同點就是自動化程度上的不同。大部分的SOA實現只達到服務級別的抽象,而微服務走的更遠,它達到了對實現和執行環境的抽象級別。
而在一個規範的微服務中,每個微服務應該被構建成胖jar(fat Jar)其中內建了所有的依賴,然後作為一個單獨的java程式存在。

三、常見的微服務元件

既然談到了微服務架構,就說一下通用的微服務都包括哪些元件:

  • 服務註冊

服務註冊是一個記錄當前可用的微服務例項的網路資訊資料庫,是服務發現機制的主要核心,服務登錄檔查詢api、管理api,使用查詢api獲得可用服務的例項,使用管理api實現註冊、登出。

  • 服務發現

服務呼叫方從服務註冊中心找到自己需要呼叫的服務的地址。可以選擇客戶端服務發現,也可以選擇服務端服務發現。

  • 負載均衡

服務提供方一般以多例項的形式提供服務,負載均衡功能能夠讓服務呼叫方連線到合適的服務節點。並且,節點選擇的工作對服務呼叫方來說是透明的。可以選擇服務端的負載均衡也可以選擇客戶端的負載均衡。

  • 服務閘道器

服務閘道器是服務呼叫的唯一入口,可以在這個元件是實現使用者鑑權、動態路由、灰度釋出、A/B測試、負載限流等功能。根據公司流量規模的大小閘道器可以是一個,也可以是多個。

  • 配置中心

將本地化的配置資訊(properties, XML, yaml等)註冊到配置中心,實現程式包在開發、測試、生產環境的無差別性,方便程式包的遷移。配置部分可以單獨使用高可用的分散式配置中心,確保一個配置服務出現問題是,其它服務也能夠提供配置服務。

  • API管理

以方便的形式編寫及更新API文件,並以方便的形式供呼叫者檢視和測試。通常需要加入版本控制的概念,以確保服務的不同版本在升級過程中都能夠提供服務。

  • 整合框架

微服務元件都以職責單一的程式包對外提供服務,整合框架以配置的形式將所有微服務元件整合到統一的介面框架下,讓使用者能夠在統一的介面中使用系統。

  • 分散式事務

對於重要的業務,需要通過分散式事務技術(TCC、高可用訊息服務、最大努力通知)保證資料的一致性。根據業務的不同適當的需要犧牲一些資料的一致性要求,確保資料的最終一致性。

  • 呼叫鏈

記錄完成一個業務邏輯時呼叫到的微服務,並將這種序列或並行的呼叫關係展示出來。在系統出錯時,可以方便地找到出錯點。同時統計各個服務的呼叫次數,確保比較熱的服務能夠分配更多的資源。

  • 支撐平臺

系統微服務化後,系統變得更加碎片化,系統的部署、運維、監控等都比單體架構更加複雜,那麼,就需要將大部分的工作自動化。現在,可以通過Docker等工具來中和這些微服務架構帶來的弊端。 例如持續整合、藍綠髮布、健康檢查、效能健康等等。可以這麼說,如果沒有合適的支撐平臺或工具,就不要使用微服務架構。

相關文章