微服務雜談(1)
==========================
###### tags: `MicroService`
# 服務與架構的演化
## Gen.1 Cleint/Server or Browser/Server架構
![](https://i.imgur.com/J3CJelb.png)
這時代主要是C/S或者B/S模式的應用與架構, 主要是面向功能來實現業務.
像是我們需要FTP或者一個能提供靜態網頁的伺服器.
這也是所謂的單一架構(Monolithic Architecture).
常見的開發流程往往是根據ER Model設計出資料表, 然後進行CRUD操作.
特點就是一個業務功能形成完整的閉環應用.
優點:
1. 開發快速
2. 成本低
3. 週期短
缺點:
1. 程式都集中在一個項目, 很難協同開發
2. 系統高度集中, 任何問題都可能導致整個系統癱瘓, 穩定性很差
3. 程式碼耦合程度高, 後期維護複雜, 功能擴展困難
4. 業務變更或系統整合時往往會導致需要重構甚至重作整套系統, 迭代時間就很難像一開始那樣快速
5. 完全綁死在某種語言之下
## Gen.2 分佈式系統/功能組件
因為前一個世代導致巨大臃腫的系統, 難以管理. 很難兼顧高質量的交付.
開始有了"高內聚"、"低耦合"、"容易擴展"、"集成"、"模組化"的概念.
"OOP"和"組件Component"的概念由然而生.
也有了Application server這概念, 也對業務進行分層架構(MVC)、橫切關注點AOP、DI/IoC. 出現了中間件(MiddleWare)這些設計模式等概念.
特點就是一些獨立組件, 多層的模式, 關注點分散, 合理的界面定義(SRP), 每一層可以再分出自己的Business Logic模組, 增加功能模組的可重複使用性.
But,就還是以單一架構的架構存在
![](https://i.imgur.com/U17SSM1.png)
優點:
1. 不同模組可以用不同技術實現了
2. 分層設計, 不同層的處理可以作成Cluster, 增加覆載量
缺點:
1. 很多架構沒把資料庫拆開分層, 所以資料庫變成瓶頸
2. 就算資料庫拆開分層, 因為資料是透過介面調用來作為傳遞, 此時就匯產生資料同步議題
3. 此時系統劃分的方式還是以功能單位進行, 稱為"垂直架構", 但因為個別系統的能力還是有限且不可靠, 依舊可能出現單點失敗
## Gen.3 SOA面向服務流程架構
很容易導致同公司但不同業務線由不同的開發團隊負責.
技術語言不同, 資料庫也不同, 彼此不相互溝通.
就是各自獨立的"煙囪式系統".
這種架構會導致重複開發, 因為不同部門之間技術允許不同, 所以可能會出現同功能的模組, 用不同語言開發. 系統之間打通成本頗高.
當然若是業務線就一組, 就沒差了:D
SOA的幾個特徵:
1. 封裝服務
2. 低耦合
3. 服務契約化
4. 服務抽象化
5. 服務重複利用化
6. 服務組合化
7. 服務自治化
8. 服務的可優化
9. 無狀態服務
10. 服務的可尋性
為此我們把服務流程的思維, 拆解成多個不同的步驟, 每個步驟的實現都可以定義成一個功能組件.
## WebService
每個組件用"Web Service"的方式進行包裝. 這樣就能達成技術實現的隔離性.
每個服務之間透過WSDL定義服務界面,透過SOAP進行調用資料編碼,傳輸.
服務之間透過UDDI進行服務發現後然後訪問.
Web Service實現了服務能運行在不同台機器和OS上, 且服務間相互發現和呼叫調用的可能, 並且透過協議傳輸資料.
## ESB 企業服務總線
ESB廣義來說就是一根管道, 用來連接各個服務節點.
ESB的存在就是為了集成基於不同協議間的不同服務. ESB做了訊息的轉化跟路由的工作, 能讓不同的服務之間互通有無.
所以它才會被稱為"總線".
通常也會用MessageQueue來實現服務之間依賴的解耦合, 替服務提供異步處理能力. 解決因併發同步調用資源造成的問題, 達到"限流&削峰"的作用.
優點講說了很多, 講講缺點:
1. 資料庫依然沒分開, 很多時候就使用一個DB做OLTP, 成為了瓶頸
2. 服務管理依然不太完善
3. 學習門檻很高
4. SOAP傳輸的內容往往大部分字段是沒太大價值的, 降低了吞吐量
5. SOA對界面規範和協議標準非常高, 不方便實施與推廣
6. 光是透過ESB和服務交互, 就出現了4次的網路會話和資料傳輸, 效率不高
7. ESB雖然可以做Cluster但很容易產生"雪崩", 因為只要在高負載情況下, ESB掛掉一台, 基本上其它台也扛不住死掉那台的壓力,跟著罷工.
![](https://i.imgur.com/hygd47H.png)
因此後面出了REST和JSON, 來改善這部份的缺陷.
## Gen.4 微服務架構(Micro Services)
![](https://i.imgur.com/fEkAz5M.png)
由於有輕量級REST協議、Container、輕量級通訊協定(JSON,protobuf、messagepack)、Service Registry、PaaS、Iaas等科技的出現.
加上微小的服務架構能夠很好彌補SOA的一些缺陷, 因為SOA沒法滿足業務的快速變化, 且當時還不盛行雲服務.
微服務目的不只是流程的解構, 更希望能圍繞在業務上(DDD)開發, 也讓小團隊也能快速開發迭代.
微服務其實沒非常準確的定義, 但有一些基本特點:
1. 使用一些相對于SOA小的服務來開發單體應用, 相互協同工作, 並各自自治
2. 每個服務運行在自己的process中
3. 使用輕量級協議(RESTful APIf、gRPC)做通訊(Lightweight Mechanism)
4. 服務是圍繞在業務能力(Business Capability)來區分規劃, 使用者情境和流程便於我們劃分服務
5. 透過自動化部屬來完成獨立部屬, 灰度測試
6. 服務可以使用不同的語言來開發, 也可以使用不同的資料儲存媒介.
7. 保持最低限度的集中式管理
8. 還是會用到SOA的相關技術
![](https://i.imgur.com/7LaKVE3.png)
### 微服務的維度
#### 業務微服務
基於業務角度來描述微服務組件, 例如會員微服務, 訂單微服務, 商品微服務
#### 技術微服務
從技術方面就是技術微服務, 快取緩存微服務, 檔案文件微服務, 數據微服務, 安全驗證微服務...
### 微服務架構的缺點
1. 多服務運維難度大幅增加
2. 系統部屬依賴度提高, 服務管理成本增加
3. 服務之間的通訊成本增加
4. 數據一致性成為大問題
5. 技術成本高, 團隊挑戰難度增加
## Gen.5 Service Mesh服務網格
![](https://i.imgur.com/m0i8nPB.png)
[nginx what-is-a-service-mesh](https://www.nginx.com/blog/what-is-a-service-mesh/)
1. Control plane: 集中配置與管理Service Mesh, 像data plane代理發送配置與控制訊號.
2. Data plane: 透過sidecar proxy這層代理, 接收並且控制網格內不同服務之間所有的出入網路數據; 達成全鍊路追蹤的目的.
...我也不熟, 期待下次鐵人賽之前能有機會玩到
# 微服務的拆分
## AKF拆分原則
![](https://i.imgur.com/Cu4KxN0.png)
參考自此書 [The Art of Scalability: Scalable Web Architecture, Processes, and Organizations for the Modern Enterprise](https://akfpartners.com/books/the-art-of-scalability)
是一群技術專家總結出來對於單體應用拓展的三個維度(X-Y-Z軸).
依照這擴展模式, 可以將一個單體架構(大方塊就是一個單體系統)無限擴展.
## X軸 水平擴容/複製
針對單體程序進行多個複製, 或者對資料庫進行擴容, 並組成cluster.
再透過負載均衡服務針對N個實例進行請求分配, 這樣每個實例只需要處理1/N的負載.
進而提高吞吐量與可用性.
### pros
1. 理論上容易, 就是複製
2. 能快速實現
### cons
1. 每個程序都能訪問到完整的數據, 所以變成資料庫之間的數據要進行複製, 成本很高
2. 組織每個人的職責難以切分, 大家還是面對這單體XD
3. 存放的資料很多, 快取命中率降低, 所需要的記憶體也增加了
## Z軸 數據分區
Z軸擴展也是複製單體程序到多個實例上, 但跟X軸不同的是, 每個實例僅負責一部分的資料子集合.
換句話說, 就是根據某些規則絕對該請求到那一個實例程序上.
舉例, B2C透過user_id是偶數的去第一台, 奇數的去第二台.
又或是電商根據SKU種類去切分片;
掏寶根據用戶的請求地區進行分區, 在各區各自建立cluster, 縮短處理時間.
或者電腦版用戶來服務A, 安卓用戶來服務B, IOS用戶來服務C.
B2B通常根據公司或是集團組織進行切分.
### pros
1. 提供了故障隔離性; 若有一區故障只有一部分資料與對應的客戶受影響
2. 因為資料數量變少了, 快取命中率上升了
3. 處理回應時間減少了
### cons
1. 實現成本頗高, 數據分區方案不好實現
2. 程序的複雜性上升, 因為要處理分區
3. 需要提昇自動化覆蓋率, 來減少佈署與維運的成本
## Y軸 功能/業務的分解
因為X跟Z軸都沒能解決開發問題還有程式或者依賴的複雜度問題.
Y軸就是來解決這維度的.
進行功能的切分, 根據業務能力來劃分.
業務能力有人會依照"動詞Verb"來劃分, 舉例:結帳、驗證、購買、註冊;
也有是按照"名詞Noun"來做分解, 舉例:客戶、訂單、報表、商品列表.
或者根據DDD的Subdomain.
定義出接口與通訊的協定. 就回到上篇的微服務的設計原則.
每個切分出來的服務都是一組專注于特定業務能力的實現, 高內聚的職責組成.
### pros
1. 程式的複雜度降低了
2. 組織規劃能按照業務來劃分
3. 提供了故障隔離性
4. 因為每組服務只負責對應業務的資料快取, 所以命中率也是很高
### cons
1. 服務管理難度變高
## 前後端分離
前後端在邏輯與物理上進行切分, 彼此都能獨立佈署, 各自專注在自身業務上.
透過後端定義好的接口與格式, 前端就能快速串接.
前後端分離後, 靜態資源也能推到CDN或是Nginx內, 減低server壓力, 讓後端資源用在處理動態資遠請求上.
## 無狀態服務
服務盡量無狀態化, 就能任意擴容. 這太抽象了XD
這狀態指的是如果一個資料會被多個服務彼此共享存取操作, 才能完成一次的事務處理, 這資料就稱為"狀態".
所有依賴于這資料的服務就是被稱為"有狀態的服務".
所以要想辦法把服務變成純粹無狀態的計算/業務服務.
這資料呢, 移到"有狀態資料的服務"上, 像是Redis, Database, 將這些有狀態的資料移到其他地方存放.
這樣子這些無狀態的業務服務, 就能隨時動態收放, 不必考慮數據同步問題了.
這也是為什麼資料庫很難動態擴容的原因, 因為有資料一致性與資料完整性的問題存在.
## RESTful通訊風格
無狀態的HTTP協議, 很適合用來擴展.
JSON格式相對於XML輕量很多, 可讀性又強.
REFTful開發框架/套件琳瑯滿目,生態圈非常完善.
滿足RESTful特性的資源被GET時, 可以被cache, 減少回應時間, 提昇體驗.
各平台or裝置都可重複利用這些服務.