架構解密從分佈式到微服務:微服務架構到底是什麼?

微服務架構

========

微服務架構概述

微服務架構 (Microservice Architecture) 是近兩年來最流行的架構術語之一,大名鼎鼎的 Martin Flower 曾這樣描述它:

“微服務” 只不過是滿大街充斥的軟件架構中的一個新名詞而已。儘管我們非常鄙視這樣的名詞,但其描述的軟件風格越來越吸引我們的注意。在過去幾年裏,我們發現越來越多的項目開始使用這種風格,以至於我們的同事在構建企業級應用時,理所當然地認爲這是一種默認開發形式。然而, 很不幸,微服務風格是什麼,應該怎麼開發,關於這樣的理論描述卻很難找到。

在互聯網時代, 在極端情況下每天都有新需求要開發上線。隨着代碼量及團隊成員的增加,傳統單體式架構的弊端日益凸顯,嚴重製約了業務的快速創新和敏捷交付,與互聯網所追求的 “唯快不破” 的目標越來越遠。這就是微服務架構興起的時代大背景。

微服務架構興起的原因

爲什麼微服務架構會快速流行? 爲什麼越來越多的人認爲微服務架構是一種默認的開發形式?

爲了弄明白上面兩個問題,我們需要先弄明白另外兩個基本問題,即我們通常講的單體架構是怎樣一種架構? 微服務架構又是怎樣一種架構? 下面這張圖顯示了兩者間的區別。

傳統的應用架構又被稱爲單體架構 (Monolithic), 表現爲業務系統的各個模塊是緊耦合的關係,各模塊運行在一個進程中,每次升級系統時基本上都要重啓整個應用進程,如果某個模塊有問題,則可能導致整個系統無法正常啓動。微服務架構則是將業務系統中的不同模塊以微服務的方式進行拆分,使每個微服務都變成 - 一個獨立的 Project,獨立編譯並且部署爲一一個獨立的進程,每個微服務都可以被部署爲多個獨立的進程對外提供服務,對外的接口方式通常是 REST 或者 RPC, 不同的微服務進程也可以被部署到多個服務器上。

我們通過對比就會發現,微服務架構通過將 - 一個龐大的單體進程分解爲相互獨立的多個微小進程,以分佈式的思想巧妙解決了傳統單體架構在互聯網時代遭遇的各種問題。所以微服務架構這種新的理念被大家快速接受並且迅速流行,是有深刻原因的。

爲了解決傳統單體架構面臨的挑戰,軟件架構先後演進出了 SOA 架構、RPC 架構、分佈式服務架構,最後演進爲微服務架構。但我們需要牢記一點: 軟件開發從來不存在銀彈,因此微服務化架構也不是銀彈,它更多的是一種架構思想與開發模式的改變,而在具體實施過程中還存在大量的技術問題及團隊問題需要妥善解決。

微服務架構實施過程中所面臨的最大技術問題之一就是開 發運維過程中的自動化。假如我們要把原來某個中等規模的系統架構改造爲微服務架構,則最少也能拆分出十幾個微服務,於是這麼多微服務進程的編譯、部署、調測及升級就演化成 - 一個浩大的工程了,如果沒有自動化的手段,則微服務化是無法推動的。說到自動化,就不得不提到容器技術,它是促進微服務架構發展的重要動力,也是微服務架構得以快速流行的重要原因。

不得不提的容器技術

容器技術其實很早就被一些互聯網公司廣泛使用了,早在 Docker 興起前的十幾年內,Google 就一直採用容 器技術支撐着世界上最大的分佈式集羣,只是一直對外保守祕密,直到祭出微服務架構利器 Kubernets。Google 之所以開源該技術,是因爲容器技術已經被業界公認爲 IT 界最重要的平臺級技術,如果不能搶佔先機和掌握話語權,就會逐步失去技術領先性所帶來的市場份額。

我們先來回顧 Docker 的發展歷史。Docker 在 2014 年才發佈 1.0 版本,成爲 2014 年的熱門技術之一。從 2004 年年初的 B 輪融資到該年年末的 DockerCon 歐洲大會,Docker 在這一年裏順風順水,就連微軟、Google、AWS 也對其青睞有加,彼時,微服務架構、雲計算、DevOps 等技術理念如日中天,Docker 恰恰完美地從技術上驅動了這些概念的落地。2015 年,CoreOS 發佈了自己的容器引擎 Rocket, 引發容器技術分裂與統 - 一的大爭論, 隨後在 Linux 基金會的干預下,Docker 公司與 CoreOS 公司握手言和,成立了 0CI (Open Container Initiative)標準委員會,它類似於當年 Java 的 JCP 組織,參與者包括 Google、RedHat 等巨頭,OCI 組織負責制定容器技術標準規範。2016 年發佈的 Docker 1.11 成爲第一一個符合 OCI 標準的容器引擎。從 2014 年到 2016 年,DockerHub 的下載量從 1 億增加到了 60 億! 2017 年,Docker 公司將 Docker 的版本區分爲企業版和社區版,開始面向企業收費,隨後又將 Docker 開源項目的代碼遷移到新的 Moby 項目上,Moby 項目被推給社區維護。Docker 公司則提供兩個產品,其中 Docker-ce 是基於 Moby 項目的免費的容器產品,Docker-ee 是它的商業產品。我們知道,在軟件開發過程中有很多環節是靠人工的,比如搭建環境、發佈安裝包 (發佈安裝包到某個 FTP 服務器上或者以 U 盤方式複製)、部署應用、升級系統等,這些過程都比較耗時耗力,很難保證任務的質量與完成時間。在分佈式系統中,一旦集羣上了規模,上述人工操作就 極易因爲大量重複性的勞動導致各種難以排查的錯誤。Docker 公司敏銳地察覺到了傳統軟件開發中的上述痛點,以創新性的標準化鏡像(Docker Image) 打包發佈應用技術爲突破口,成功定義了 “軟件生命週期中的標準化與自動化” 的新標準。下面這張圖給出了 Docker 的標準化鏡像的示意圖。

Docker 鏡像是一個包含了目標程序所有依賴文件的 “All in one" 的分層壓縮包,你可以認爲它是一個沒有 Linux 內核但有 Linux 文件系統和基礎命令的 - 一個最精簡版的虛機,在這個虛機裏包括了已經安裝和配置好的目標應用二進制代碼,以及運行目標程序中的所有其他依賴包,比如一個運行在 Torncat 中的完整應用的 Docker 鏡像組成如下。

啓動鏡像的過程就是啓動打包製作鏡像時指定的目標程序,比如對於 Tomcat 來說,就是運行 tomcat.sh 命令。此外,由於鏡像本身已經固化了安裝過程及配置參數,所以通過 Docker 鏡像創建和啓動一個容器就變成了一個非常簡單並且不會出錯的命令:

綜上所述,我們通過 Docker 技術可以很容易地將軟件開發從源碼編譯、鏡像打包、測試環境部署、版本發佈、系統升級到生產環境發佈等生命週期中的所有重要環節自動化,這是加速微服務架構實施的重要技術保障手段,下圖是這個過程的一個簡單示意圖。

如何全面理解微服務架構

微服務架構是從 SOA 架構、RPC 架構、分佈式服務架構演變而來的,它也具有以下特點。

首先,微服務架構是一個分佈式系統架構。也就是說,分佈式系統設計的原則、經驗,以及常用的分佈式基礎設施和中間件依然是微服務架構中的重要組成部分,如果拋開分佈式架構中的這些技術,只是空談微服務架構,則好像空中樓閣。

其次,與 SOA 架構 - - 樣, 微服務架構與開發語言無關,它並沒有公認的技術標準規範與實施方案,更多地體現了一種被 普遍接受的新的設計理念和指導思想,歸納下來有以下幾點。

●輕量級的服務: 每個服務實例都只提供密切相關的一種或幾種服務,粒度小、輕量級, 便於微團隊快速開發、部署、測試與升級。

●松耦合的系統: 微服務之間的調用也是客戶端的一種調用方式,僅限於接口層的耦合,避免了服務實現層的深耦合,因此服務之間的依賴性被降到最低,系統的整體穩定性與平衡升級 (滾動升級) 能力得到切實保障。

●平滑擴容能力: 由於在微服務架構平臺中原生地提供了某種微服務負載均衡機制,因此對於無狀態的微服務,可以通過獨立部署多個服務進程實例來提升整體的吞吐量。由於每個微服務都可以單獨擴容,因此微服務架構具有很強的運行時的性能調優能力。

●積木式的系統: 每個微服務通常都被設計爲複雜業務流程中一個最小粒度的邏輯單元 (積木), 某個完整的業務流程就是合理編排(搭積木) 這些微服務而形成的工作流,升級或者重新開發一一個新業務流程變成了簡單的積木遊戲,而隨着微服務越來越多,業務單元 (微服務) 的複用價值越來越大,因此新業務快速上線的需求變成了一個可準確評估和預測的計劃任務。

最後,微服務架構也有某些事實上公認的框架與工具,目前最經典的有以下三個微服務架構開源平臺。

上述這三個經典微服務架構平臺能提供完備的微服務架構與管理工具,在技術上各有千秋, 從總體來看,Google 出品的 Kubermetes 是很優秀的微服務架構,也是本章要重點分析和講解的微服務架構。

接下來,我們一起看看在實施 -- 個微服務架構項目的過程中可能遇到的問題及應對策略。

首先,架構師需要對項目組的全體成員進行培訓,讓大家明白微服務架構的思想和優點,培訓的一個重要目標是要讓大家明白,微服務架構在實施過程中會給項目組帶來很明顯的技能升級需求,不管是對於開發人員還是對於運維測試人員來說,這都是一個難 得的新技術學習與自我技能提升的好機會,希望大家頂住壓力完成項目。

其次,要正確選擇一個合適的微服務架構平臺而不是自己研發。這種大型基礎平臺的研發成本很高、開發週期長而且平臺可持續升級的可能性較低,因此目前很少有公司會自己進行研發,即使是 RedHat 這樣有實力、有經驗的開源軟件服務型公司,也放棄了自己的微服務架構,轉而應用 Kubernetes。那麼,如何選擇適合自己公司和項目組的微服務架構平臺呢? 以本節提到的三個典型的微服務架構平臺爲例,可參考如下條件進行選擇。

●如果整個團隊對 容器技術沒有什麼經驗,則排除 Kubermnetes, 否則優先選擇它。

●如果系統的性能要求很高,同時很多高頻流程中涉及大量微服務的調用,以及微服務之間也存在大量調用,則先考慮以 RPC 二進制方式通信的微服務平臺,優先考慮 Ice, 其次是 Kubernetes,最後是 Spring Cloud。

(3) 團隊的重構。在微服務模式下,整個系統從架構層來看基本只分爲展現層與微服務層。

考慮到微服務在整個系統中的重要性,建議團隊中的骨幹技術人員成爲微服務層的開發主力,大家作爲 - 一個總體對所有微服務代碼負責,-- 起設計每個微服務接口,一起評審所有微服務代碼,而在具體的開發過程中,則可以將相似度較高的幾個微服務模塊交由同一個人研發。這種模式基本符合二八定律。

(4) 高質量的文檔。在微服務架構下,文檔特別是每個微服務的接口文檔的重要性越來越高,因爲每個使用微服務的人都要清楚當前所要調用的微服務是哪個、應該調用哪個接口、參數有什麼含義,以及返回值的意義。因此,我們需要一份詳細 並且準確的微服務接口文檔,還,要保持文檔與代碼同步更新。

接下來看看如何設計系統中的微服務。一開始, 我們其實並不很清楚要將哪些功能和服務設計成一個微服務, 以及一個微服務究竟應該包括多少個接口,每個接口應該如何設計。筆者的建議是先粗粒度地劃分微服務,每個微服務包括比較多的接口以減少微服務的個數,這樣可以減少開發、程序打包、測試及部署的工作量,有利於快速推進項目。

系統中的微服務按照調用客戶端的不同,可以劃分爲流程控制類、接口類及基礎核心類三種,如下圖所示。

一般來講,這三種不同的微服務的接口設計也有所不同。

流程控制類微服務主要面向 UI 調用, 所以它的接口設計應該以頁面展示的便利性爲第一目標,即大部分情況下采用 JSON 或 TEXT 文本的方式傳遞參數與返回值,並且考慮在調用邏輯出錯的情況下告訴客戶端錯誤的代碼與原因,於是這類微服務的返回值通常會是下面的結構體:

1public class CallResult
2int resultCode; //返回代碼, 0爲成功,其他爲調用錯誤
3String resultData;//調用結果, 通常爲JSON的字符串
4String errmsg; //調用錯誤的時候,展示給用戶的可讀錯誤信息
5

接口類微服務主要面向第三方系統,所以特別需要注意安全問題,因此在接口設計中必須有安全措施,比較常見的方案是在調用參數中增加 Token, 並考慮參數加密的問題,同時建議接口類微服務在實現過程中重視日誌的輸出問題,以方便接口聯調,並方便在運行期間排查接口故障,在日誌中應該記錄入口參數、關鍵邏輯分支、返回結果等重要信息。

基礎核心類微服務主要被 UI 及其他兩種微服務所調用, 在這類微服務的接口設計中主要考慮效率和調用的方便性。建議將其設計得與普通 Java 類的接口看起來一樣,這樣可以避免將很多複雜 Bean 對象作爲參數及返回值時不但增加調用者的負擔而且降低接口性能。

在微服務設計中,我們還需要考慮接口兼容性的問題,比如如下微服務接口設計:

1public void doBusiness (paraml, param2, param3)
2
1public class XXXBean
2{
3private String paraml;
4private String param2;
5private String param3;
6private String param4;
7}
8public void doBusiness (XXXBean thebean)
9

這樣一來, 對舊接口無需重新編譯, 只要升級 XXXBean 所在的 JAR 文件即可兼容舊版本。

來源:

https://www.toutiao.com/i6937907188505657870/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/cbdAfnrwJJ3l34730ldBKQ