微服務雜談(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裝置都可重複利用這些服務.