因為Martin Fowler和Chris Richardson兩位大神的佈道,及NetFlix和Amazon公司的實踐,國內對於微服務的一些基礎問題理解基本一致,但受限於自身單體應用的限制,過度到微服務架構,又要各想辦法,具體問題具體看了。本篇描述一下微服務架構的基本概念及個人的一些理解。“微服務架構是一種架構模式,它提倡將單一應用程式劃分成一組小的服務,服務之間相互協調、互相配合,為使用者提供最終價值。每個服務執行在其獨立的程式中,服務和服務之間採用輕量級的通訊機制相互溝通(通常是基於HTTP的Restful API).每個服務都圍繞著具體的業務進行構建,並且能夠被獨立的部署到生產環境、類生產環境等。另外,應儘量避免統一的、集中的服務管理機制,對具體的一個服務而言,應根據業務上下文,選擇合適的語言、工具對其進行構"---- Martin Fowler的部落格
微服務的特徵與界定
單體應用vs 微服務架構
優點
1:提升開發交流,每個服務足夠內聚,足夠小,程式碼容易理解;
2:服務獨立測試、部署、升級、釋出;
3:按需定製的DFX,資源利用率,每個服務可以各自進行x擴充套件和z擴充套件,而且,每個服務可以根據自己的需要部署到合適的硬體伺服器上;每個服務按4:需要選擇HA的模式,選擇接受服務的例項個數;
5:容易擴大開發團隊,可以針對每個服務(service)元件開發團隊;
6:提高容錯性(fault isolation),一個服務的記憶體洩露並不會讓整個系統癱瘓;
7:新技術的應用,系統不會被長期限制在某個技術棧上;
缺點
沒有銀彈,微服務提高了系統的複雜度;開發人員要處理分散式系統的複雜性;服務之間的分散式通訊問題;服務的註冊與發現問題;服務之間的分散式事務問題;資料隔離再來的報表處理問題;服務之間的分散式一致性問題;服務管理的複雜性,服務的編排;不同服務例項的管理。
Chris Richardson提出的微服務的三維擴充套件模型:
X軸,服務例項水平擴充套件,保證可靠性與效能;
Y軸,功能的擴充套件,服務單一職責,功能獨立;
Z軸,資料分割槽,資料獨立,可靠性保證;
通訊問題
微服務的拆分一般會帶來IPC通訊的問題。通訊機制需要完備可靠,服務之間的通訊選擇應儘量單一,從兩個維度對通訊的模式進行劃分:
第一個維度是一對一還是一對多:
一對一:每個客戶端請求有一個服務例項來響應。
一對多:每個客戶端請求有多個服務例項來響應。
第二個維度是這些互動式同步還是非同步:
同步模式:客戶端請求需要服務端即時響應,甚至可能由於等待而阻塞。
非同步模式:客戶端請求不會阻塞程式,服務端的響應可以是非即時的。
微服務架構認為,服務間通訊應該就只有這幾種模式。AC出於時延、程式設計模型等方面的考慮,提供了一套通訊機制,業務之間的通訊要按需選用。
服務的發現與註冊
一般的微服務架構裡都有兩層API GetWay,一層是外部API GetWay,用於使用者訪問系統;一層是內部API GetWay,內部服務之間的API GetWay。內部API GetWay要解決的問題就是服務發現和服務註冊。從這也能看出來,為什麼通訊的方式要儘量單一,API GetWay有一項工作就是協議轉換。
微服務可能是HA主備的,也可能是LB的,怎麼找到一個服務?有兩種思路,客戶端發現(上圖),客戶端去註冊中心查詢服務例項列表,自行選擇;另一種是服務端發現(下圖),新增LB模組,客戶端把請求發向LB,由LB根據負載均衡策略選擇服務例項;
微服務登錄檔的典型實現:
ETCD : 是一個高可用,分散式的,一致性的,鍵值表,用於共享配置和服務發現。兩個著名案例包括Kubernetes和Cloud Foundry。 ZK: 是一個廣泛使用,為分散式應用提供高效能整合的服務。Apache ZooKeeper最初是Hadoop的子專案,現在已經變成頂級專案。
微服務架構的部署
微服務架構對於部署的要求:
部署速率,Amazon與NetFlix都有千個服務,每個服務都有持續部署的要求,Amazon的服務每秒都會部署一次;
部署自動化,一切都要自動化,IaaS與PaaS解決I層與P層自動化部署,微服務有自動部署與運維工具,並實現Auto-Scaling;
部署提供基礎機制,為實現分散式部署要求,部署機制一般都有資源池化、服務的生命週期來看,部署服務與服務註冊是一體的;
部署的粒度:
VM: 部署系統管理的VM的生命週期,如當前AC的iDeploy部署,把AC部署拆分為每個VM的安裝、配置與啟動;這種方式粒度粗,支撐不了微服務的部署(除非一個服務佔用一個VM);
App: 管理應用的生命週期及部署形態,生命週期分為部署、配置、啟動、升級等,部署形態有主備、LB、Daemon等;
Container: 相比於APP,容器有更好的隔離性和移植性;
微服務:一般的微服務要麼是APP,要麼是Container,但AC就不是。受限於ONOS架構,我們的服務是一組feature;
MS部署的解決方案:
TOSCA: 雲應用拓撲標準,一種描述雲化部署的DSL,我司主推一個標準,PaaS的部署系統和MANO用的都是TOSCA;
Kubernetes:Google開源的容器管理系統,提出了Pod/Service/Labels等概念,以ETCD為中心,PaaS基於K8S開發出了我司的雲化部署平臺;
Mesosphere:DCOS,資料中心作業系統,基於mesos實現資源池化,有自身的編排工具;分散式LAB基於DCOS的思想做出了一套部署與叢集管理系統(HASEN);
微服務的劃分
微服務的劃分主要是保證微服務功能內聚,職責單一。一般使用DDD(Domain Drive Design)的思想與方法對微服務進行劃分,這種方法有點類似於資料庫ER圖的劃分,不斷分解資料,保證關係型資料庫符合原子性、冗餘性的正規化要求。當然,微服務的劃分比資料表劃分更復雜,也沒有微服務正規化的概念,但思想是一致的。更多的內容,請參考《領域驅動設計》這本書。
分散式一致性
有兩個大的思路:全域性的分散式事務;事件驅動;
分散式事務就是現在AC的思路,在設計開發中;
事件驅動,忽略了事務的概念,由每個服務在應用層面儲存服務的狀態,服務之間的通訊使用事件機制通知;此種方法可以保證微服務間的獨立性,但把問題交給了服務的設計者;具體事件驅動的案例見參考材料;
資料隔離問題
微服務之間資料隔離可以保證服務的獨立升級與部署,資料隔離有三個維度:
資料表級隔離;資料表之間獨立,沒有外來鍵關係;
資料庫級隔離;不同服務有不同的資料庫;
DBMS級隔離;不同服務有不同的資料庫管理系統;
一般做到資料庫級隔離就可以了,服務之間的資料交換使用服務間介面。
從單體到微服務
微服務架構是一個衍生架構,都是從單體架構演化而來的。
因為微服務架構本身的複雜性,初創系統出於快速開發、快速驗證的考慮,很少在一開始就使用微服務架構。加之微服務的概念在這兩年才火,大型單體應用也是看到了開發與維護的成本在不斷增加,才會有轉型微服務的動力。因此,如何從單體到微服務是一個普遍問題。
從單體到微服務的原則:
逐步演進,不要全部重構。
全部重構,帶來極大的成本和風險,系統會有很長的不穩定期。而且,最終的效果也不會很好,在設計時很難想到所有問題。微服務架構的演化思路應該是一步步鋪基礎設施,一點點拆分微服務。
演化建議(個人建議)
1. 不要增加新的耦合;
不要有編譯依賴,如直接import其它模組的類;
使用版本建議的通訊方式,不要使用osgiservice,這個耦合還是很強;不要直接訪問其它模組的資料表;
避免不必要的親合性,注意特性之間的狀態,如A特性訪問B特性的2個請求有狀態,那這兩個特性例項就有親合性;
2. 前後端分離;
前後端業務分離,前端之間不會耦合,能前端做的,就放在前端;
3. 獨立的服務逐漸拆出;
逐步拆出功能獨立的微服務,對有特殊DFX要求的微服務也可以優先拆出;
DevOps與微服務架構
DevOps是09年提出來的概念,但一直沒有太火。直到14年,容器與微服務架構的提出,DevOps才得到了快速的發展。DevOps不單是一個實現自動化的工具鏈,而是組織、流程與技術的結合。組織上強調全棧團隊、團隊特性專一、團隊自治;技術上打通開發與運維;流程上強調端到端、視覺化、灰度升級、A/B測試等。
對於DevOps,MS不是必須的,但MS為DevOps提供了最好的架構支撐,對於組織和流程的要求也是一致的。所以,也有人稱MS是DevOps架構。
目前國內多家巨頭都對微服務的支援投入巨大,例如騰訊雲micro-service、華為雲微服務雲應用平臺ServiceStage等等。