技術論談:總體性認知微服務及其架構設計思考

技術論談:總體性認知微服務及其架構設計思考

微服務

軟件架構是一個包含各種組織的系統組織,這些組件包括 Web服務器, 應用服務器, 數據庫,存儲, 通訊層), 它們彼此或和環境存在關係。系統架構的目標是解決利益相關者的關注點。

技術論談:總體性認知微服務及其架構設計思考

Conway’s law: Organizations which design systems[...] are constrained to produce designs which are copies of the communication structures of these organizations.

(設計系統的組織,其產生的設計和架構等價於組織間的溝通結構。)

Monolithic架構

技術論談:總體性認知微服務及其架構設計思考

Monolithic比較適合小項目,優點是:

開發簡單直接,集中式管理, 基本不會重複開發

功能都在本地,沒有分佈式的管理開銷和調用開銷。它的缺點也非常明顯,特別對於互聯網公司來說(不一一列舉了):

開發效率低:所有的開發在一個項目改代碼,遞交代碼相互等待,代碼衝突不斷

代碼維護難:代碼功能耦合在一起,新人不知道何從下手

部署不靈活:構建時間長,任何小修改必須重新構建整個項目,這個過程往往很長

穩定性不高:一個微不足道的小問題,可以導致整個應用掛掉

擴展性不夠:無法滿足高併發情況下的業務需求

微服務架構

微服務是指開發一個單個小型的但有業務功能的服務,每個服務都有自己的處理和輕量通訊機制,可以部署在單個或多個服務器上。微服務也指一種種松耦合的、有一定的有界上下文的面向服務架構。也就是說,如果每個服務都要同時修改,那麼它們就不是微服務,因為它們緊耦合在一起;如果你需要掌握一個服務太多的上下文場景使用條件,那麼它就是一個有上下文邊界的服務,這個定義來自DDD領域驅動設計。

相對於單體架構和SOA,它的主要特點是組件化、松耦合、自治、去中心化,體現在以下幾個方面:

  • 一組小的服務
  • 服務粒度要小,而每個服務是針對一個單一職責的業務能力的封裝,專注做好一件事情。
  • 獨立部署運行和擴展
  • 每個服務能夠獨立被部署並運行在一個進程內。這種運行和部署方式能夠賦予系統靈活的代碼組織方式和發佈節奏,使得快速交付和應對變化成為可能。
  • 獨立開發和演化
  • 技術選型靈活,不受遺留系統技術約束。合適的業務問題選擇合適的技術可以獨立演化。服務與服務之間採取與語言無關的API進行集成。相對單體架構,微服務架構是更面向業務創新的一種架構模式。
  • 獨立團隊和自治
  • 團隊對服務的整個生命週期負責,工作在獨立的上下文中,自己決策自己治理,而不需要統一的指揮中心。團隊和團隊之間通過鬆散的社區部落進行銜接。

我們可以看到整個微服務的思想就如我們現在面對信息爆炸、知識爆炸是一樣的:通過解耦我們所做的事情,分而治之以減少不必要的損耗,使得整個複雜的系統和組織能夠快速的應對變化。

我們為什麼採用微服務呢?

"讓我們的系統儘可能快地響應變化" - Rebecca Parson

讓我們的系統儘可能快地去響應變化。其實幾十年來我們一直在嘗試解決這個問題。如果一定要在前面加個限制的話,那就是低成本的快速響應變化。上世紀90年代Kent Beck提出要擁抱變化,在同期出現了諸多輕量級開發方法(諸如 XP、Scrum);2001年敏捷宣言誕生,之後又出現了精益、看板等新的管理方式。如果說,這些是為了儘快的響應變化,在軟件開發流程和實踐方面提出的解決方案,那麼微服務架構就是在軟件技術和架構層面提出的應對之道。

技術論談:總體性認知微服務及其架構設計思考

微服務的總體特性描述如下:

Autonomous (自主性)

微服務是一個功能單元,它提供了一系列面向業務領域或常用工具的功能的API;

Isolated (隔離性)

微服務是部署單元, 它可以作為一個單元進行修改、測試和部署,而不會影響解決方案的其他方面;

Elastic (伸縮性)

A Microservice is stateless; it can be horizontally scaled up and down as needed

微服務是無狀態的, 它可以根據需要進行水平放大和縮小;

Resilient (彈性)

A Microservice is designed for failure; it is fault tolerant and highly available

微服務是為處理失敗而設計的,它具有容錯性和高可用性;

Responsive

(響應性)

A Microservice responds to requests in a reasonable amount of time

微服務在合理的時間內響應請求;

Intelligent (智能化)

The intelligence in a system is found in the Microservice endpoints not ‘on the wire’

系統中的智能可以在Microservice端點找到,而不是"在線上";

Message Oriented (面向消息)

Microservices rely on HTTP or a lightweight message bus to establish a boundary between components; this ensures loose coupling, isolation, location transparency, and provides the means to delegate errors as messages

微服務依靠HTTP或輕量級消息總線來建立組件之間的邊界。這確保了松耦合、隔離、位置透明性,並提供了將錯誤作為消息進行委派的手段;

Programmable (可編程)

Microservices provide API’s for access by developers and administrators

微服務提供API供開發人員和管理員訪問;

Composable (可組合)

Applications are composed from multiple Microservices

應用程序由多個微服務組成;

Automated (自動化)

The lifecycle of a Microservice is managed through automation that includes development, build, test, staging, production and distribution

微服務的生命週期通過自動化進行管理,包括開發、構建、測試、分段、生產和分發。

服務之間如何通信

技術論談:總體性認知微服務及其架構設計思考

一般同步調用比較簡單,一致性強,但是容易出調用問題,性能體驗上也會差些,特別是調用層次多的時候。RESTful和RPC的比較也是一個很有意 思的話題。一般REST基於HTTP,更容易實現,更容易被接受,服務端實現技術也更靈活些,各個語言都能支持,同時能跨客戶端,對客戶端沒有特殊的要 求,只要封裝了HTTP的SDK就能調用,所以相對使用的廣一些。RPC也有自己的優點,傳輸協議更高效,安全更可控,特別在一個公司內部,如果有統一個 的開發規範和統一的服務框架時,他的開發效率優勢更明顯些。就看各自的技術積累實際條件,自己的選擇了。而異步消息的方式在分佈式系統中有特別廣泛的應用,他既能減低調用服務之間的耦合,又能成為調用之間的緩衝,確保消息積壓不會沖垮被調用方,同時能 保證調用方的服務體驗,繼續幹自己該乾的活,不至於被後臺性能拖慢。不過需要付出的代價是一致性的減弱,需要接受數據最終一致性;還有就是後臺服務一般要 實現冪等性,因為消息發送出於性能的考慮一般會有重複(保證消息的被收到且僅收到一次對性能是很大的考驗);最後就是必須引入一個獨立的broker,如 果公司內部沒有技術積累,對broker分佈式管理也是一個很大的挑戰。

技術論談:總體性認知微服務及其架構設計思考

微服務優點

  • 每個微服務都很小,這樣能聚焦一個指定的業務功能或業務需求。
  • 微服務能夠被小團隊單獨開發,這個小團隊是2到5人的開發人員組成。
  • 微服務是松耦合的,是有功能意義的服務,無論是在開發階段或部署階段都是獨立的。
  • 微服務能使用不同的語言開發。
  • 微服務允許容易且靈活的方式集成自動部署,通過持續集成工具,如Jenkins, bamboo 。
  • 一個團隊的新成員能夠更快投入生產。
  • 微服務易於被一個開發人員理解,修改和維護,這樣小團隊能夠更關注自己的工作成果。無需通過合作才能體現價值。
  • 微服務允許你利用融合最新技術。
  • 微服務只是業務邏輯的代碼,不會和HTML,CSS 或其他界面組件混合。
  • 微服務能夠即時被要求擴展。
  • 微服務能部署中低端配置的服務器上。
  • 易於和第三方集成。
  • 每個微服務都有自己的存儲能力,可以有自己的數據庫。也可以有統一數據庫。

微服務架構的缺點

  • 微服務架構可能帶來過多的操作。
  • 需要DevOps技巧 (http://en.wikipedia.org/wiki/DevOps).
  • 可能雙倍的努力。
  • 分佈式系統可能複雜難以管理。
  • 因為分佈部署跟蹤問題難。
  • 當服務數量增加,管理複雜性增加。

需要考慮的問題

  • 單個微服務代碼量小,易修改和維護。但是,系統複雜度的總量是不變的,每個服務代碼少了,但服務的個數肯定就多了。就跟拼圖遊戲一樣,切的越碎,越難拼出整幅圖。一個系統被拆分成零碎的微服務,最後要集成為一個完整的系統,其複雜度肯定比大塊的功能集成要高很多。
  • 單個微服務數據獨立,可獨立部署和運行。雖然微服務本身是可以獨立部署和運行的,但仍然避免不了業務上的你來我往,這就涉及到要對外通信,當微服務的數量達到一定量級的時候,如何提供一個高效的集群通信機制成為一個問題。
  • 單個微服務擁有自己的進程,進程本身就可以動態的啟停,為無縫升級的打好了基礎,但誰來啟動和停止進程,什麼時機,選擇在哪臺設備上做這件事情才是無縫升級的關鍵。這個能力並不是微服務本身提供的,而是需要背後強大的版本管理和部署能力。
  • 多個相同的微服務可以做負載均衡,提高性能和可靠性。正是因為相同微服務可以有多個不同實例,讓服務按需動態伸縮成為可能,在高峰期可以啟動更多的相同的微服務實例為更多用戶服務,以此提高響應速度。同時這種機制也提供了高可靠性,在某個微服務故障後,其他相同的微服務可以接替其工作,對外表現為某個設備故障後業務不中斷。同樣的道理,微服務本身是不會去關心繫統負載的,那麼什麼時候應該啟動更多的微服務,多個微服務的流量應該如何調度和分發,這背後也有一套複雜的負載監控和均衡的系統在起作用。
  • 微服務可以獨立部署和對外提供服務,微服務的業務上線和下線是動態的,當一個新的微服務上線時,用戶是如何訪問到這種新的服務?這就需要有一個統一的入口,新的服務可以動態的註冊到這個入口上,用戶每次訪問時可以從這個入口拿到系統所有服務的訪問地址。這個統一的系統入口並不是微服務本身的一部分,所以這種能力需要系統單獨提供。
  • 還有一些企業級關注的系統問題,比如,安全策略如何集中管理?系統故障如何快速審計和跟蹤到具體服務?整個系統狀態如何監控?服務之間的依賴關係如何管理?等等這些問題都不是單個微服務考慮的範疇,而需要有一個系統性的考慮和設計,讓每個微服務都能夠按照系統性的要求和約束提供對應的安全性,可靠性,可維護性的能力。
技術論談:總體性認知微服務及其架構設計思考

API為什麼很重要

•服務價值的精華體現

•可靠、可用、可讀

•只有一次機會

技術論談:總體性認知微服務及其架構設計思考

實現一個API網關作為所有客戶端的唯一入口。API網關有兩種方式來處理請求。有些請求被簡單地代理/路由到合適的服務上,其他的請求被轉給到一組服務。

技術論談:總體性認知微服務及其架構設計思考

相比於提供普適的API,API網關根據不同的客戶端開放不同的API。比如,Netflix API網關運行著客戶端特定的適配器代碼,會向客戶端提供最適合其需求的API。

API網關也可以實現安全性,比如驗證客戶端是否被授權進行某請求。

設計要素

•Version

•RequstID

•Auth&Signature

•RateLimit

•Docs

•ErrorCode&Message

技術論談:總體性認知微服務及其架構設計思考

微服務治理

•按需伸縮

–部署與監控運維成本

•獨立部署

–機器數量與部署成本

•業務獨立

–服務依賴、治理,版本管理、事務處理

•技術多樣性

–環境部署成本、約定成本

•運行狀態治理

–監控、限流、SLA、LB、日誌分析

•服務註冊與發現

•部署

–快速、複製、擴容

–單機開發

•調用

–安全、容錯、服務降級、調用延時

技術論談:總體性認知微服務及其架構設計思考

技術論談:總體性認知微服務及其架構設計思考

服務容錯

當企業微服務化以後,服務之間會有錯綜複雜的依賴關係,例如,一個前端請求一般會依賴於多個後端服務,技術上稱為1 -> N扇出. 在實際生產環境中,服務往往不是百分百可靠,服務可能會出錯或者產生延遲,如果一個應用不能對其依賴的故障進行容錯和隔離,那麼該應用本身就處在被拖垮的風險中。在一個高流量的網站中,某個單一後端一旦發生延遲,可能在數秒內導致所有應用資源(線程,隊列等)被耗盡,造成所謂的雪崩效應(Cascading Failure),嚴重時可致整個網站癱瘓。

技術論談:總體性認知微服務及其架構設計思考

服務依賴

技術論談:總體性認知微服務及其架構設計思考

服務框架

  1. 服務註冊、發現、負載均衡和健康檢查,假定採用進程內LB方案,那麼服務自注冊一般統一做在服務器端框架中,健康檢查邏輯由具體業務服務定製,框架層提供調用健康檢查邏輯的機制,服務發現和負載均衡則集成在服務客戶端框架中。
  2. 監控日誌,框架一方面要記錄重要的框架層日誌、metrics和調用鏈數據,還要將日誌、metrics等接口暴露出來,讓業務層能根據需要記錄業務日誌數據。在運行環境中,所有日誌數據一般集中落地到企業後臺日誌系統,做進一步分析和處理。
  3. REST/RPC和序列化,框架層要支持將業務邏輯以HTTP/REST或者RPC方式暴露出來,HTTP/REST是當前主流API暴露方式,在性能要求高的場合則可採用Binary/RPC方式。針對當前多樣化的設備類型(瀏覽器、普通PC、無線設備等),框架層要支持可定製的序列化機制,例如,對瀏覽器,框架支持輸出Ajax友好的JSON消息格式,而對無線設備上的Native App,框架支持輸出性能高的Binary消息格式。
  4. 配置,除了支持普通配置文件方式的配置,框架層還可集成動態運行時配置,能夠在運行時針對不同環境動態調整服務的參數和配置。
  5. 限流和容錯,框架集成限流容錯組件,能夠在運行時自動限流和容錯,保護服務,如果進一步和動態配置相結合,還可以實現動態限流和熔斷。
  6. 管理接口,框架集成管理接口,一方面可以在線查看框架和服務內部狀態,同時還可以動態調整內部狀態,對調試、監控和管理能提供快速反饋。Spring Boot微框架的Actuator模塊就是一個強大的管理接口。
  7. 統一錯誤處理,對於框架層和服務的內部異常,如果框架層能夠統一處理並記錄日誌,對服務監控和快速問題定位有很大幫助。
  8. 安全,安全和訪問控制邏輯可以在框架層統一進行封裝,可做成插件形式,具體業務服務根據需要加載相關安全插件。
  9. 文檔自動生成,文檔的書寫和同步一直是一個痛點,框架層如果能支持文檔的自動生成和同步,會給使用API的開發和測試人員帶來極大便利。Swagger是一種流行Restful API的文檔方案。

微服務系統底座

一個完整的微服務系統,它的底座最少要包含以下功能:

  • 日誌和審計,主要是日誌的彙總,分類和查詢
  • 監控和告警,主要是監控每個服務的狀態,必要時產生告警
  • 消息總線,輕量級的MQ或HTTP
  • 註冊發現
  • 負載均衡
  • 部署和升級
  • 事件調度機制
  • 資源管理,如:底層的虛擬機,物理機和網絡管理

以下功能不是最小集的一部分,但也屬於底座功能:

  • 認證和鑑權
  • 微服務統一代碼框架,支持多種編程語言
  • 統一服務構建和打包
  • 統一服務測試
  • 微服務CI/CD流水線
  • 服務依賴關係管理
  • 統一問題跟蹤調試框架,俗稱調用鏈
  • 灰度發佈
  • 藍綠部署

容器(Docker)與微服務

•容器夠小

–解決微服務對機器數量的訴求

•容器獨立

–解決多語言問題

•開發環境與生產環境相同

–單機開發、提升效率

•容器效率高

–省錢

•代碼/image一體化

–可複用管理系統

•容器的橫向與縱向擴容

–可複製

–可動態調節CPU與內存

容器(Docker)與微服務

•Image管理

•系統安全管理

•系統成熟度

•社區成熟度

開發方式影響

隨著持續交付概念推廣以及Docker容器普及,微服務將這兩種理念和技術結合起來,形成新的微服務+API + 平臺的開發模式,提出了容器化微服務的持續交付概念。

下圖傳統Monolithic的DevOps開發隊伍方式:

技術論談:總體性認知微服務及其架構設計思考

這種整體型架構要求產品隊伍橫跨產品管理 Dev開發 QA DBA 以及系統運營管理,而微服務架構引入以後,如下圖:

技術論談:總體性認知微服務及其架構設計思考

微服務促進了DevOps方式的重組,將一個大臃腫的整體產品開發隊伍切分為根據不同微服務的劃分的產品隊伍,以及一個大的整體的平臺隊伍負責運營管理,兩者之間通過API交互,做到了松耦合隔絕。

技術論談:總體性認知微服務及其架構設計思考

技術論談:總體性認知微服務及其架構設計思考

  • 首先需要考慮構建DevOps能力,這是保證微服務架構在持續交付和應對複雜運維問題的動力之源;
  • 其次保持服務持續演進,使之能夠快速、低成本地被拆分和合並,以快速響應業務的變化;
  • 同時要保持團隊和架構對齊。微服務貌似是技術層面的變革,但它對團隊結構和組織文化有很強的要求和影響。識別和構建匹配架構的團隊是解決問題的另一大支柱。
  • 最後,打造持續改進的自組織文化是實施微服務的關鍵基石。只有持續改進,持續學習和反饋,持續打造這樣一個文化氛圍和團隊,微服務架構才能持續發展下去,保持新鮮的生命力,從而實現我們的初衷。

微服務的實施是有一定的先決條件:基礎的運維能力(如監控、快速配置、快速部署)需提前構建,否則就會陷入如我們般被動的局面。推薦採用基礎設施及代碼的實踐,通過代碼來描述計算和網絡基礎設施的方法,使得圖案度i可以快速安全的搭建和處理由新的配置代替的服務器,服務器之間可以擁有更高的一致性,降低了在“我的環境工作,而你的環境不工作”的可能,也是為後續的發佈策略和運維提供更好的支撐。

技術論談:總體性認知微服務及其架構設計思考

由於Docker引入,不同的微服務可以使用不同的技術架構,比如Node.js Java Ruby Python等等,這些單個的服務都可以獨立完成交付生命週期,如下:

技術論談:總體性認知微服務及其架構設計思考

微服務案例

Netflix的微服務架構如下,著重全球分發 高可擴展性和可用性:

技術論談:總體性認知微服務及其架構設計思考

Twitter的微服務架構,注重高效的可擴展的數據中心:

技術論談:總體性認知微服務及其架構設計思考

最後,在進行IT微服務治理時,請仔細認識到微服務的優缺點,以便有更好的取捨,下面是實踐需要注意的內容:

  • 微服務架構的優點:
  1. 每個服務都比較簡單,只關注於一個業務功能。
  2. 微服務架構方式是松耦合的,可以提供更高的靈活性。
  3. 微服務可通過最佳及最合適的不同的編程語言與工具進行開發,能夠做到有的放矢地解決針對性問題。
  4. 每個微服務可由不同團隊獨立開發,互不影響,加快推出市場的速度。
  5. 微服務架構是持續交付(CD)的巨大推動力,允許在頻繁發佈不同服務的同時保持系統其他部分的可用性和穩定性。
  • 微服務架構的缺點:

微服務的一些想法在實踐上是好的,但當整體實現時也會呈現出其複雜性。

  1. 運維開銷及成本增加:整體應用可能只需部署至一小片應用服務區集群,而微服務架構可能變成需要構建/測試/部署/運行數十個獨立的服務,並可能需要支持多種語言和環境。這導致一個整體式系統如果由20個微服務組成,可能需要40~60個進程。
  2. 必須有堅實的DevOps開發運維一體化技能:開發人員需要熟知運維與投產環境,開發人員也需要掌握必要的數據存儲技術如NoSQL,具有較強DevOps技能的人員比較稀缺,會帶來招聘人才方面的挑戰。
  3. 隱式接口及接口匹配問題:把系統分為多個協作組件後會產生新的接口,這意味著簡單的交叉變化可能需要改變許多組件,並需協調一起發佈。在實際環境中,一個新品發佈可能被迫同時發佈大量服務,由於集成點的大量增加,微服務架構會有更高的發佈風險。
  4. 代碼重複:某些底層功能需要被多個服務所用,為了避免將“同步耦合引入到系統中”,有時需要向不同服務添加一些代碼,這就會導致代碼重複。
  5. 分佈式系統的複雜性:作為一種分佈式系統,微服務引入了複雜性和其他若干問題,例如網絡延遲、容錯性、消息序列化、不可靠的網絡、異步機制、版本化、差異化的工作負載等,開發人員需要考慮以上的分佈式系統問題。
  6. 異步機制:微服務往往使用異步編程、消息與並行機制,如果應用存在跨微服務的事務性處理,其實現機制會變得複雜化。
  7. 可測性的挑戰:在動態環境下服務間的交互會產生非常微妙的行為,難以可視化及全面測試。經典微服務往往不太重視測試,更多的是通過監控發現生產環境的異常,進而快速回滾或採取其他必要的行動。但對於特別在意風險規避監管或投產環境錯誤會產生顯著影響的場景下需要特別注意。
  • 關於微服務架構的取捨
  1. 在合適的項目,合適的團隊,採用微服務架構收益會大於成本。
  2. 微服務架構有很多吸引人的地方,但在擁抱微服務之前,也需要認清它所帶來的挑戰。
  3. 需要避免為了“微服務”而“微服務”。
  4. 微服務架構引入策略 – 對傳統企業而言,開始時可以考慮引入部分合適的微服務架構原則對已有系統進行改造或新建微服務應用,逐步探索及積累微服務架構經驗,而非全盤實施微服務架構。


分享到:


相關文章: