1. 程式人生 > >【總結】AWS 雲端計算環境中的Microservices(微服務)架構

【總結】AWS 雲端計算環境中的Microservices(微服務)架構

1.邱洋總結

  • 微服務不是石頭縫裡面蹦出來的,是基於類似SOA、Blackboard、C/S等應用架構基礎上,並融合敏捷開發、DevOps等理念的基礎上發展而來
  • 微服務相比傳統應用優點明顯(快速部署、去中心、良好的隔離性等),缺點也不少(更復雜、通訊損耗、測試成本高)
  • 微服務不僅僅是一種新型的應用設計方法,使用這種架構的企業的組織架構可能也需要作出適當調整
  • AWS針對微服務設計了ECS(基於EC2的容器服務)、Lambda(基於事件驅動的計算平臺,開發人員只要編寫javascript或java邏輯就行,lambda負責執行工作,類似HPC的執行模式)
  • 原來AWS的ElasticBeanstalk就已經在底層使用Docker來進行應用環境交付了,只是限定更加多(需要指定語言平臺,如java、php、.net等)而ECS則沒有這麼多要求。EB好比GAE而ECS更像EC2

2.關於微服務(Microservices)

2.1為什麼需要微服務

原有3層的應用架構(表現層、邏輯層、持久層–資料層)每個大層面的應用程式都有大量邏輯進行包裹,因此開發、維護和管理起來非常費時費力,且由於開發週期長都存需求落後風險

圖片1

而微服務的開發模式不同,它的思路是將每個大層面的應用,再次分解,將每個相對獨立的小模組都變成一個獨立的程式(所謂一個小的服務)每個服務都的獨立執行在程序中,獨立部署,每個服務之間通過輕量級的方式進行互動,例如http api。不同的服務可以不同的開發語言,資料儲存儲存機制。這樣就可以敏捷的開發和維護應用,時間週期也變得非常短

圖片2

2.2 為什麼微服務會出現?

技術發展帶來的複雜性,開發時間上的開銷,大環境所承擔的各種風險,相關理念與開發思想(如敏捷開發)共同推波助瀾的結果

微服務是以歷史上存在的、流行過的程式設計架構為基石的,而非石頭縫裡蹦出來的,這些架構包括:

  • Blackboard架構:背後的理念是,一系列獨立的程式攜手合作,致力於處理同一個資料結構
  • Client/Server架構:客戶機和伺服器結構。它是軟體系統體系結構,通過它可以充分利用兩端硬體環境的優勢,將任務合理分配到Client端和Server端來實現
  • Component Based架構:在元件物件模型的支援下,通過複用已有的構件,軟體開發者可以“即插即用”地快速構造應用軟體
  • Peer-To-Peer
    架構:不同於主從式架構,網路上的每個使用端或程式的實體都擁有相同的等級,同時扮演使用者端與伺服器的角色。
  • Service Oriented 架構:大名鼎鼎的SOA架構,是構造分散式計算的應用程式的方法。它將應用程式功能作為服務傳送給終端使用者或者其他服務。

另一方面,微服務不僅傳承了各種應用架構,而且受到眾多軟體設計領域的思想的影響,比如:

  • 領域設計驅動(分析模型化的複雜業務)
  • 敏捷方法(提升效率減少浪費)
  • 持續交付(更快、更可靠、更頻繁的應用部署)
  • 虛擬化和IaaS(簡化基礎架構環境)
  • DevOps(讓團隊更加小巧)

2.3 微服務的特徵

  • :每個服務只做一件事情,並且目標是把事情做好、做極致 。例如業內有些人的甚至用程式碼尺寸衡量(例如100行、1000行以內的程式碼)。
  • 執行在獨立的程序中:不同的服務可以執行在不同的主機之上
  • 輕量級通訊機制:指的是服務和服務之間,通過輕量級的通訊機制,進行溝通(輕,是指通訊跟語言和平臺無關,例如json、xml等)。而相反的傳統重量級通訊機制比如(.net remoting或java rmi)
  • 鬆耦合:不需要改變依賴,只需要改變當前服務本身,並獨立部署。這意味著該服務的部署和執行,和其他服務之間呈現獨立的姿態

2.4 微服務的優缺點

優點:

  • 良好的隔離性和可用性,場景:某一個服務的故障,並不會影響到其他無關的服務
  • 獨立交付速度大大提高,場景:現在強調的持續部署、持續開發對交付速度有很高要求,Microservices可以做到。而傳統的Monolithic一體化應用部署的交付速度提升非常難,對基礎架構、對環境、對應用測試的要求高,很難做到
  • 去中心化的管理,場景:在管理部署傳統應用的時候,都有部署一個打包的應用、有一個關鍵核心應用,就是是一箇中心點。而Microservices並沒有一箇中心,因此可以在運維過程中各團隊可以針對部件獨立部署,DevOps ,降低風險

缺點:

  • 複雜性,Microservice本質上是分散式,而分散式系統本身存在複雜性,需要開發、測試和運維人員等都需要有處理複雜系統的經驗
  • 服務的操作開銷,Microservice因為有很多服務,相比傳統架構有很多服務間通訊的開銷,因此在效率上不如傳統Monolithic。並且一般都需要遵循DevOps進行管理模式和流程。
  • 服務介面不匹配後的問題?雖然Microservice使用標準化介面,但由於服務多而且不同服務的介面存在版本,一旦某服務版本失去了控制,或與其他服務通訊的匹配,則會出現不可控的風險
  • 測試,相比傳統應用架構,每次釋出版本,都需要整個生態系統測試,因此整體測試時間更長更復雜
  • 扇形增加的需求數,主要原因是隨著服務的增加,資料流量就會大幅度增加

3.微服務設計

3.1 康威定律 Conway’s Law(應用架構對組織架構有要求)

圖片3

任何設計系統的組織……必然會產生以下設計結果,即其結構就是該組織溝通結構的寫照

—-翻譯—–
有什麼樣的組織架構,就有什麼樣的軟體產品。用傳統的組織架構去開發Microservice就會出問題

3.2 傳統應用組織架構(SILOs)

圖片4
傳企業應用架構如下:
- 產品團隊
- 使用者互動體驗
- 開發團隊
- 測試團隊
- 資料庫團隊
- 系統管理
- 網路管理
- 儲存管理等

傳統應用架構採用一體化(Monolithic)應用使用這種模式是比較好的,但是Microservice使用這種架構會有問題(因為每個服務都可能存在需要搭配這樣的班子的情況),而這種組織架構下,資訊在團隊間溝通成本是非常大的

3.3 針對Microservice,組織需要作出調整(DevOps)

圖片5

調整方法:針對Microservice的各個service建立一個個敏捷小型的高效團隊,每個小型團隊針對每個服務(貫穿於整個應用的各個服務模組)負責,獨立進行相應的開發與管理工作

圖片10
Microservice的架構跟DevOps有密切的關聯,Microservice是DevOps思想逐步演化的結果,而DevOps也是實現Microservice最好的工具

3.4 如何設計 smaller(真正的小) 的服務

推薦一本書:Building Microservice

圖片6

將服務做小的關鍵點總結:

  • 每個服務要關注“業務”領域,每個服務解決一個具體問題
  • 結構上呈現“鬆散、耦合”架構,便於後期部署、測試、除錯
  • “有邊界”的上下文,並不需要每個服務周邊的部分—其他服務、依賴服務等,團隊只關注服務本身和服務的API;傳統應用的需求分析需要對全域性需求有了解並設計後才能開發,而微服務可以更快讓團隊開始
  • 每個服務都可以獨立部署
  • 需要配套思想對應的工具(如DevOps的工具等)
  • 鼓勵大家使用新技術(建議:伯斯塔爾法則,做的時候要保守,接受的時候要開放)
  • 自動化的文化
  • 能在兩週內重寫的東西(衡量Microservice的服務小的標準)
  • 兩張披薩團隊(亞馬遜內部思路,一個靈活敏捷的團隊應該控制在10個人左右)

圖片9

3.5 Microservice的實踐- Netflix IPC Stack

圖片7
★Netflix IPC Stack 1.0
Netflix內部的一個應用,1.0採用傳統的SILOs風格的應用,不符合Microservice的設計風格

圖片8
★Netflix IPC Stack 2.0
Netflix 在 IPC Stack 2.0開始抽象出了比較粗的服務,並獨立部署在彼此隔離的容器中,且通過HTTP API進行互動

4. Microservice的相關技術與雲服務

4.1 容器計算技術

圖片11

傳統虛擬機器(擁有hypervisor)會存在效能損耗,而docker採用LXC技術取消了hypervisor,直接使用Linux Kernel,提升了效能。而docker的這種快速部署和管理能力,正好和Microservice的服務快速部署吻合

4.2 AWS上的docker執行模式有3種

  1. EC2(直接使用EC2服務中內建了docker能力的AMI啟動例項來使用docker)
  2. AWS Elastic BeanStalk(利用docker技術進行封裝,來自動部署彈性web應用和服務架構的託管類應用,可支援php、java、.net等語言環境)
  3. EC2 Container Service(提供針對docker容器的視覺化、流水線式的管理能力)

4.3 EC2 Container Service

ECS的關鍵元件

1、機群(Container Cluster)
- 區分割槽域
- 相當於資源池
- 相當於容器例項的分組
- 啟動時為空、動態擴容與調整

2、容器例項(執行容器的EC2例項)
- 包含一個EC2例項
- 在例項中存在一個Docker程序
- 在例項中存在一個 ECS的代理(Agent是開源的,用goLang開發)
圖片12

3、任務(就是一個個docker 容器)
- 每個例項可以設定多個任務
- 任務是作業的單位
- 允許任務分組和設定關聯
- 任務執行在EC2例項中

4、任務 定義
- 通過json來定義任務
- 包括:docker hub模板、cpu數量、記憶體等
圖片13

圖片14

任務 排程(實現計算資源的管理)
- 長期執行的服務(Long-running services)
- 批量執行任務(RunTask for bach jobs)
- 整合第三方排程器schedulers

4.4 Microservice的實踐- Coursera(使用了ECS)

4.4.1 一個mooc網站

圖片15

4.4.2 Coursera的需求

之前Coursera開發了一套傳統的網際網路應用架構,有很多程式單元,而每一個單元裡面有很多服務(粒度很粗),主要的需求是

  • 可靠性:因為服務的人員比較多,所以如果應用宕機則對公司聲譽2.影響大
  • 更容易開發:網際網路公司生存壓力,需要快速上線更多應用滿足客戶需求,另一方面,小並且公式化的開發模式是必須的
  • 更快部署
  • 成本的考慮:希望投入產出比更高
  • 更高效的運維:只有1個運維人員,現有環境維護太複雜
    圖片16

4.4.3 Coursera的選擇之路

Coursera嘗試了很多方法,最後不希望自己運維和折騰了,所以選擇了ECS
1.自己的現有技術
- 嘗試過,但是不可靠
- 操作困難

2.MESOS
- 非常強大,實際操作過程中易用性差
- 需要一直與之匹配的DevOps團隊

3.Kubernetes
- 在GCE上表現的很好,其他地方就不行了(而GCE是google的IaaS平臺)

4.使用ECS
- 維護成本幾乎為0
- Coursera已經使用了AWS的服務,如IAM等希望繼續沿用
- 開發人員更好理解和操作(docker本身還是主機不用改變語言開發方式),學習成本低

4.4.4 最終Coursera改造後的Microservice架構

  • 大量的使用ECS的work部署Microservice中的service
  • 前端+排程器 設計
    • 生成的請求(通過API呼叫 或 內部通訊都通過scheduler來分配)
    • 新請求儲存在 SQS 佇列中
    • 根據來自其他服務的狀態 而 處理請求
  • 後端設計
    • 試圖通過ECS 的API 來執行task(不是通過介面操作,更快更及時)
    • 如果任務失敗,則任務自動回滾到佇列中,之後重試
    • 保持任務狀態的跟蹤,並更新 Cassandra資料庫(一種NoSQL資料庫)

圖片17

4.5 AWS的Lambda(託管的、事件驅動架構的計算平臺服務)

特點:

  • 零管理:是一個計算平臺而不是一個windows或linux,因此不需要過多的管理環境相關的東西(例如多少cpu、記憶體、頻寬等)
  • 事件驅動:基於事件產生對程式碼塊的自動呼叫
  • 計算平臺:對於開發人員來講,就是一個計算平臺,提交程式碼然後等待結果即可
  • 使用者可以專注業務邏輯而不是基礎架構:使用者針對業務進行服務開發(可以使用javascript、java等)並設定好觸發機制上傳程式碼,而AWS Lambda負責後續的工作,如容量、擴充套件、部署、容錯、監控、日誌等
  • 自動化擴充套件:使用者僅僅負擔所使用的費用,不會超過/低於資源調配
  • 細粒度的定價:價格計量單位是毫秒(單位是100ms)對於短時間任務非常有價值,沒有最低消費,可以免費試用
  • 事件以不同的形態和尺寸發生:S3事件通知、DynamoDB Streams事件、Kinesis(事件流)事件、定製化事件
  • 同步非同步都可呼叫:針對不同的業務場景可以選擇同步非同步模式呼叫,如某些應用日誌產生問題後非同步響應觸發lambda呼叫。或定製實踐發生後同步觸發lambda呼叫

圖片18

基礎架構的擴充套件性、利用率情況

資源種類 擴充套件性 利用率
企業自有IDC 周級
Amazon EC2 分鐘級
Container 較高
AWS Lambda 毫秒 最高

4.6 Microservice的實踐-AWS Lambda使用方法示例

4.6.1 一個內容管理系統(CMS)

具體需求包括:
- 允許使用者上傳頭像
- 需要將圖片儲存
- 需要為頭像製作縮圖,在不同的web位置使用

4.6.2 傳統情況

  • 一個CMS應用搞定所有工作,涉及的流程包括:上傳頭像→儲存圖片→將圖片生成縮圖

  • 傳統情況下修改任意環節(如儲存圖片)則需要將CMS系統重新打包然後更新

4.6.2 Lambda改造情況

  • 使用者上傳圖片到S3中,一個新的S3物件將觸發lambda函式來轉換成縮圖,將縮圖儲存到S3的另外一個bucket
  • 另一方面將元資料儲存到DynamoDB中,當一個新的儲存條目後觸發一個建立ECS的task的事件去執行其他操作(如生成GIF圖)

圖片18