ODCA最佳實踐翻譯:基于云感知的應用架構設計-下篇

云應用設計模式

下面的章節詳細介紹了一些設計模式,這些現有的設計模式可以有效地應用到云服務應用程序設計中去。

電路開關

電路開關(Circuit Breaker)設計模式由Michael Nygard所提出,Netflix將它作為云服務的一部分進行了進一步的發展。在該模式下,一個“電路開關”被插入在發送請求和處理請求的組件之間。就像在一個電路中,一個開關有兩個狀態:閉合或者斷開。當電路開關閉合則整個電路激活,能量被傳輸;對于軟件來說,請求被發送到正常處理它的組件上。當電路開關斷開則意味著正常路徑被打斷,則系統執行一個備份的代碼路徑。電路開關用于檢測電路中的故障然后使電路倒換到一個安全的備份狀態。以下條件可以觸發軟件電路斷開:

  • 一個到遠端服務的請求超時;
  • 遠端服務的請求隊列滿了,意味著遠端服務不能處理更多的請求了;

這些因素可以設計一個錯誤率作為閾值,當閾值超過時,電路開關進入到斷開狀態。

當電路開關斷開,組件轉移到備用狀態,有三種備用狀態的策略:

  • 失敗透明。通過設計一個備用API的方式產生一個替代響應,例如該方法可以根據緩存構建返回響應或者根據默認值返回一個響應。
  • 失敗靜默。對請求返回空值。在返回值內容對于呼叫服務并不關鍵的場景是有用的。
  • 快速失敗。產生一個包含錯誤碼的響應,這意味著呼叫服務必須處理這些對用戶來說有意義的錯誤。

理想情況下,組件最好應該失敗透明,但實際上往往不是總能做到這點。

注意電路開關和根據條件進行響應(“如果請求超時,則返回錯誤碼500”)并不同:

  • 電路開關的觸發條件是隨著時間變化的,根據一個滑動窗口,而不是一個單一的失?。?/li>
  • 當電路開發觸發后會進行保持,備份狀態會持續到開關被重置;
  • 電路開關的狀態組件外部是可見的,工具可以看到電路開關的狀態以便進行故障處理;
  • 電路開關可以由組件外部進行控制;

在Netflix,電路開關周期性地讓部分請求通過,如果請求處理成功,則開關重置,所有的請求都允許通過。下圖描述了電路開關的邏輯:

Netflix通過儀表盤將電路開關的狀態可視化出來。這使得組件狀態更加一目了然,比傳統的使用異常碼的組件更加容易狀態可視化。

下面的截圖顯示了一個電路開發服務在儀表盤中可視化的樣子:

** 電路開關模式 **
以下是電路開關設計模式的要點:

  • 優點
    • 增強容錯性
    • 對于組件失敗可視化(通過對電路開發狀態的可視化)
  • 使用場景
    • 為了減少由于網絡或者虛機實例失敗造成的超時或者延遲
    • 為了避免錯誤級聯以及復雜的上游錯誤處理(失敗透明,失敗靜默)

請求隊列

請求隊列設計模式包含一個組件,將請求消息(或者任務)放入一個或者多個待處理隊列中。計算節點從隊列中取出請求消息進行處理。隊列作為請求和處理服務之間的緩沖區可以防止重負載導致的服務失敗或者超時。這種模式是生產者消費者或者基于隊列的負載均衡模式的一個變種。

將請求放入隊列,可以方便負載被分布的計算集群進行處理。如果一個計算節點失敗,其它的工作者可以繼續處理隊列中的請求。這提供了分級的容錯性可以確保云計算應用程序的高可用性。

消息隊列可以充當閥門的作用,可以通過阻止請求進入控制服務的資源消耗。如果某個服務超過了每秒給定的消息配額,可以阻塞后續的請求進入該服務。對于進入的請求在入隊前可以應用性能計數器,一旦某一客戶端的請求超過了云應用程序的配置閾值,則后續的消息被阻塞。在互聯網應用中,可以給客戶端發送HTTP 429錯誤碼(含義:請求過多)以及通過報文頭中的Retry-After指示多久服務無法響應客戶端的請求。下圖用Microsoft Developer Network描述了隊列是如何有效地進行服務間的負載均衡的。

** 消息隊列模式 **
下面是消息隊列設計模式的特點:

  • 優點
    • 增加容錯性以支持高可用
    • 對于高訪問的API可以提升性能
  • 使用場景
    • 需要管理應用程序的故障轉移(容錯)
    • 對于高訪問的API降低負載
    • 將閥門機制作為自動伸縮的替代策略

合并請求

合并請求設計模式將對同一API的相鄰請求進行緩存合并。例如,播放視頻的網絡應用程序需要從數據中心獲得視頻的元信息(例如片長),傳統的實現中每個用戶單獨發送請求獲取視頻的元信息,利用請求合并,一定時間間隔內的請求可以并合并成一個,這樣減少了網絡帶寬消耗以及API的負載,使得API端可以水平擴展支持更大量的并發用戶。

為了合并請求,對API使用一個代理(Proxy)將給定時間窗(例如10ms)內的請求進行排隊,周期地將隊列內的消息合并成一個請求發給API。響應消息則并發地分發給所有請求者。這種優化對高并發的請求很有意義。如果隊列中只有一個消息,它也得等夠時間窗的時間長度才能發送,這會引入一定的延遲可能會影響性能。一般請求會落在時間窗內的任何位置,所以引起的平均時延等于時間窗的一半(對于10ms的時間窗,平均延遲為5ms)。下圖給出請求合并的一個例子:

對象變更通知

傳統的緊耦合的軟件架構中,系統組件間的關系是固定的。例如兩個組件A和B存在依賴,當A變化的時候需要通知B,這時A知道B只有一個實例,同時也知道B的位置。如果B由于某種原因不可訪問了,A無法將通知發送給B,這時A必須實現某種機制去處理這種場景。A和B之間的這種依賴導致了系統存在單點失敗,影響系統的可擴展性。

分布式系統中如果存在許多這樣的靜態依賴,每一個都會降低系統整體的彈性。對該問題的一個解決方式是為架構引入冗余,用一對多的關系代替組件間的一對一關系。例如A不再依賴于固定的B,而是存在B的多份實例,任意B的失敗給A帶來的影響可以忽略不計。

對象變更通知模式,也被稱作觀察者模式,在這種處理模式下使用可以增強系統的彈性。

該模式下,通知組件(A)實現一個可觀察(Observable)的接口,觀察者(B)通過該接口注冊自己感興趣的變化。當A發生一些變化,它則將變化通知給所有的觀察者們。觀察者可以通過變化通知消息直接獲取變化內容(push mode),也可以根據事件內容再去向被觀察對象請求變化細節(pull mode)。

云環境下該模式可以使得應用程序具備彈性擴展的能力。因為組件不再是緊耦合,額外的實例可以動態的添加以處理增加的負載。這對于計算或者I/O密集型的任務做并行化很有價值。例如Netflix為了適應不同終端設備和網絡帶寬,需要將視頻轉換成不同碼率的好多版本。利用對象變更通知模式,當第一個新的視頻加載到存儲時,一個代理檢測到存儲設備發生了變化則觸發產生一組轉碼任務去并行處理不同碼率的視頻版本,當計算完成,這些轉碼任務自行關閉。

** 對象變更通知模式 **
下面是對象變更通知模式的要點:

  • 優點:
    • 提高容錯性
    • 增加可擴展性
    • 更高的資源利用率
  • 使用場景
    • 為了將計算密集型任務并行化
    • 為了減少單點失敗
    • 為了減少組件間的耦合以便可以替換組件的實現

服務發現

在分布式應用中,組件需要知道對端服務地址才能向對端發送請求。在傳統的分層架構中,服務的主機名存在配置文件中。DNS用來查詢主機的實際IP地址。為了可擴展性,IP可以指向一個負載均衡使得負載可以分發給多個服務實例。

云環境具有高度的動態性,服務和組件實例不斷的由于負載的變化或者故障原因而產生和消失。在云中基于DNS的負載均衡可能會將請求轉給不存在或者已經失敗的服務實例。解決方案是實現一套云服務的發現機制,只有正常的服務實例是可被定位的。這樣的服務發現機制應該具備以下能力:

  • 提供給組件一種直接將請求發給可用實例的方式
  • 支持服務實例的動態注冊和注銷
  • 對于給定實例可以查詢它的狀態

Netflix實現的服務注冊“Eureka”具備上述能力。它是一個分布的服務,同時嵌入在應用程序的服務組件和客戶端中。

如下圖,Eureka服務維持了一組健康服務的注冊列表。注冊的服務需要定期發送心跳更新它們的狀態。如果和已注冊服務之間連接失敗,則發現服務在一個超時周期后將它從注冊列表里移去。當新的服務啟動的時候,它們向Eureka注冊,同樣當實例終止或者失敗他們自動的從注冊中去掉不會影響別的服務。注冊機制意味著只有準備好處理消息的服務才會在注冊列表里面,正在上線過程中的服務不會。

每個客戶端組件內嵌了Eureka的客戶端程序,它維護了一個從Eureka服務端拷貝下來的注冊服務的一份緩存。通過這種方式可用服務的知識在整個環境中備份著,這天然為系統提供了容錯性,避免Eureka服務端故障導致網絡不可用。Eureka客戶端根據某種算法將請求負載均衡到不同的處理服務上,默認的負載均衡算法是輪詢,可以對算法進行修改。

實際上,Eureka將決定請求發送給哪一個服務的決策放到每一個客戶端,將這種行為封裝在客戶端的代碼庫中,服務端開發者則降低了對服務端不可用的設計。因為注冊列表中的同類服務會輪流處理請求,Eureka要求服務是無狀態的。這是可擴展性和彈性的先決條件,是云應用架構的普遍原則。

因為客戶端組件緩存著可用服務實例,所以它們能夠在Ereka服務端故障的時候繼續運行。當分布式環境跨越多個數據中心或者云,這時網絡發生分區故障后每個區域的Eureka服務可以繼續運行,因為服務的注冊信息在每個區域都存在冗余。

** 服務發現模式 **
以下是服務發現模式的要點:

  • 優點:
    • 提高容錯性
    • 簡化基礎架構的管理
    • 簡化動態環境的應用程序開發
  • 使用場景:
    • 在需要支持自動擴展的場景

微服務

微服務設計模式中,一個單體(monolithic)服務的功能被分解成一系列良好設計的單一職責的微服務。例如,郵件消息系統中的提供消息創建、讀取、更新和刪除的消息存儲服務,可以將其每個功能分解成一個獨立的服務,其中讀取服務僅提供讀取消息的功能。微服務有很多優點,包含更好的彈性和性能、更高的可靠性以及易于部署。

彈性的提高是因為微服務下每個小的服務都可以獨立的伸縮。例如,如果消息的讀取遠大于寫的請求,這時額外的讀服務可以被創建來消化負載。而在原來消息存儲作為一體的情況下,整個服務都需要復制,這時水平擴展就會引起不必要的資源浪費。

微服務簡化了軟件的開發和部署。軟件開發人員可以擁有一個微服務完整的開發和獨立發布的權利,如果消息讀取服務的開發者改進了消息的緩存功能,則可以直接將此發布到生產環境而不用與其它消息存儲功能進行集成。這種解耦的特性開發使得開發人員可以按照自己的時間表并行工作。

"部署到云上最好的方法是什么,最好的方法是編寫可重用的代碼,我們如何快速響應業務變化?答案似乎是微服務。通過創建小的獨立的服務,程序可以專注將一件事做好 - 我們減少了開銷,增加了可伸縮性和彈性。開發成百上千的小的程序,去除過多的耦合,促使開發人員重新審視與重構架構,最終創建可以快速響應的、具有彈性的云應用程序。"

  • Michael Forhan, AppFirst blog: “Lessons from Distill”

Netflix已經開發了一套微服務升級部署的方法。這種方法中不再一次升級服務的所有實例,而是部署新的版本的一個實例進行冒煙測試。如果新的版本失敗了,對整個系統的影響很小,開發人員可以修復問題快速的重新部署。如果微服務的新版本運行正常,一組新的實例則被創建分擔現存在實例的負載。新的實例會被密切監控幾小時以便確認沒有內存泄露等其它問題。如果發現存在問題,則將負載重新路由回舊的實例。如果新的微服務版本最終功能一切正常,舊的實例則會在一定時間后自動關閉。Netflix通過持續交付的方式將這一過程自動化,從而加快部署,實現了快速迭代,而且降低了錯誤的可能。Nerflix采用了一套簡單的哲學:錯誤不可避免,但是需要能夠快速恢復而不影響整體服務。

微服務的另一個好處是如果發生故障,很容易定位出故障的原因,因為錯誤范圍往往內聚在微服務的邊界內,容易定位出哪次升級導致了故障。

** 微服務模式 **
下面是微服務設計模式的要點:

  • 優點:
    • 減少升級部署的負擔
    • 減少由于服務共筑引起的副作用
    • 提高彈性
    • 對于問題根源的可視化程度更高
    • 提高開發效率
  • 使用場景:
    • 在大的系統中,需要大規模的彈性和成本效益
    • 為了消除單點失敗
    • 為了改進性能
    • 為了支持對關鍵系統的頻繁升級

服務無狀態化

無狀態要求服務不保存每個客戶請求之間的客戶端狀態,相應的每個請求消息必須攜帶服務需要處理的所有上下文信息。這一設計模式對于分布式系統提供了很多的好處,包括:

  • 可靠性??煽啃泽w現在一個客戶端可以對一個失敗的請求進行重試,而不用服務端重構失敗前的狀態;
  • 可擴展性。無狀態化可以通過幾個途徑提高可擴展性。因為服務端實例不存儲狀態,任何實例都可以處理任何客戶端的任何請求,隨著請求負載的增加,在不影響現有實例的情況下可以動態地啟動其它實例來進行負載分擔。此外由于服務端不存儲任何客戶端狀態,服務的資源消耗相對輕量級,可以提高整體資源利用率使得每個服務端可以支持更高的請求負載。
  • 可視化。從運維的角度看,每個請求和響應消息的凈荷中包含了所有交互信息,這使得可以容易使用請求代理等方案,對請求的語義具有更大的可視化空間。
  • 簡單。當服務不再存儲狀態,則就沒有必要管理請求在多次事務間的數據。無狀態服務的實現也相對容易,更容易調試。無狀態服務可預測性更高,由于巧合引起的bug也會被消除。

無狀態服務的缺點則是消息的負載會比較大,因為消息中攜帶了所有服務端需要處理它的上下文。然而無狀態設計整體帶來的優點要比缺點更多。

** 無狀態服務模式 **
下面是無狀態服務設計模式的要點:

  • 優點:
    • 增加可靠性
    • 增加可擴展性
    • 提高了請求消息管理和監控的可視化
    • 實現簡單
    • 相比狀態敏感的服務bug更少
  • 使用場景
    • 任何需要高擴展性的分布式系統

配置服務

傳統應用程序的運行時配置通常依靠應用的文件系統上的一個多個文件。在某些場景,可以對這些文件進行運行時修改(也就是說文件被熱加載)。更一般的場景下這些配置文件在應用啟動的時候進行加載,這意味著配置修改需要重新啟動或者加載應用程序,這時該過程會導致應用停機以及付出額外的管理成本。

通常這些配置文件被存儲和管理在應用程序本地,導致應用程序部署的每個節點上都需要冗余地存儲配置文件。當應用程序的集群增長,每個節點配置文件的管理開銷開銷也隨之增長。

外部配置存儲

將應用程序的配置文件持久化在外部數據存儲區中,為云計算應用程序的配置提供一個中心化的管理倉庫。將配置移出本地應用實例,可以讓跨越應用程序的配置管理和共享變得容易。外部配置數據存儲可以可以在不同的運維環境中變化。

數據庫或者文件倉庫可以提供對配置文件讀取和寫入的最大靈活性。敏感信息如密碼等可以在應用程序動態構建的時候動態注入,或者通過應用程序啟動時動態加載的環境變量進行加載。下圖說明了外部配置存儲和應用程序加載過程。

運行時重配

良好設計的云計算應用程序應該具備高可用性,盡量減少停機時間。任何需要應用程序重新部署的配置變化都會增加停機時間。運行時重配需要應用程序能夠檢查配置變更從而在運行時重新加載配置。

支持運行時重配需要應用程序源代碼設計能夠處理配置變更通知消息。一般這會通過觀察者模式來實現。應用程序向中心配置服務注冊配置變更消息。當通知消息被觸發,例如新的配置文件上傳,應用程序將得到通知并獲得最新的配置,將其加載到內存。

Apache Zookeeper是Apache軟件基金會用來支持運行時重配的開源項目。ZooKeeper提供了一個集中服務用來管理配置信息、命名、并提供分布式同步和組服務。ZooKeeper可以被用作共享配置服務,也就是用來做集群協調。

使用ZooKeeper來存儲配置信息具有兩個主要的好處:

  1. 新的節點可以接收到如何連接到ZooKeeper的指令,然后從ZooKeeper上下載所有的配置信息同時決策它們在集群中的合適角色。
  2. 應用程序可以訂閱配置的更改,在運行時允許通過ZooKeeper客戶端獲得最新的配置完成云計算應用程序的集群行為修改。ZooKeeper運行在稱作“ensemble”的服務器集群上進行應用程序的數據狀態共享,它可以協調云計算應用程序集群的分布式一致性。

** 配置服務模式 **
下面是配置服務設計模式的要點:

  • 優點:
    • 對于配置管理的獨立集中的數據存儲;
    • 減少應用程序配置管理的負擔;
    • 減少應用停機;
  • 應用場景:
    • 任何需要應用程序配置的分布式系統;
    • 需要減少停機時間的高可用場景;

授權模式

在云環境下,不能假定網絡是安全的,因為很多因素都不在應用程序所有者的控制下。這意味著第三方可能監聽或者重定向傳輸的數據。另外的風險是API可能會被多租戶云環境中的其它租戶訪問,或者被外部互聯網進行訪問。這種暴漏性導致了風險,API可能成為DoS攻擊的對象,或者導致信息泄露以及使服務遭到惡意破壞。云應用程序更容易受到這些攻擊,因為它們是由互相依賴的服務組成,每一個網絡依賴的接口都會增加應用程序的風險。解決方案是為網絡流量進行加密以及為API提供授權保護機制。

API授權

API授權保證了只有被信賴的API客戶能夠訪問API,防止服務被惡意訪問,還可以支持對不同客戶端分配不同的權限。例如,一些客戶端僅被授權只讀權限,而其它有讀寫權限。授權還可以用來限制哪些客戶可以訪問服務。例如,數據庫的API可以通過訪問限制來確保客戶端使用合適的數據訪問權限。

應用程序通常使用用戶名和密碼來進行認證。這種方法有兩個主要的問題:

  1. 客戶端需要保存用戶名和密碼,這使得賬戶信息可能被泄露,而密碼機制則是出了名的脆弱的。
  2. 管理每個組件的用戶名和密碼增加了復雜性和管理開銷以及配置錯誤的風險。

OAuth2.0協議(RFC6749)引入了基于令牌進行訪問控制的概念來解決這些問題。在OAuth,授權服務器給客戶特定的令牌來提供特定的訪問權限。

如下圖所示,對于OAuth控制服務:

  • 客戶端向授權服務請求對待訪問服務的認證令牌(1);
  • 授權服務校驗身份驗證憑據,如果有效返回訪問令牌(2);
  • 客戶端在所有對服務端的請求中攜帶訪問令牌(5);
  • 對每一個請求,服務端通過授權服務檢查令牌的合法性(6);
  • 授權服務對被訪問服務提供和令牌相關聯的一組權限(7);
  • 服務端使用這組權限來決定每個請求的操作權限,執行相應的動作然后給客戶端返回響應數據(8);

除了在每個請求中傳遞令牌,為了安全性還會給令牌設置生命周期。當令牌過期后,客戶端使用一個刷新令牌來請求一個新的訪問令牌。

** 授權認證設計模式 **
下面給出了授權認證設計模式的要點:

  • 優點:
    • 提高安全性;
    • 細粒度的服務訪問控制;
  • 適合場景:
    • 對于所有客戶端和服務端之間的請求;

云應用成熟度評估

云應用成熟度模型提供了一個簡單的方法來評估應用程序的云成熟度水平,正如Richardson成熟度模型用來評估REST API的成熟度一樣。成熟度模型為提高應用程序在云中的可靠性、彈性以及擴展性提供了演進路標。

下表列出了四個層次,Level 3表明最高的成熟度層次,Level0表明應用程序還不是云感知的。

成熟度0:虛擬化級

Level 0 是最低的成熟度層次。一個用程序只要正常運行在虛級化資源上(例如虛機)上就算是Level 0。應用程序的實例從某一鏡像中啟動,或者利用腳本動態啟動。這種程序往往耦合緊密,各組件之間顯式的依賴于彼此。

成熟度1:松耦合級

Level 1 在 Level 0 的基礎上引入松耦合的要求。松耦合意味著組件不需要和彼此緊密地依賴。如果一個組件故障了,其它組件不受影響,整個應用程序依舊能夠正常的工作。松耦合的組件之間往往通過異步交互,能讓應用程序更容易擴展。

松耦合的另一方面要求組件間提供的接口與具體實現解耦,服務可以透明地從一種實現變更到另一種實現或者同時支持多種不同的實現。

將計算和存儲分離也有利于實現松耦合。通過將計算和存儲分離,應用程序不再受低層存儲機制的影響,使得存儲可以獨立地不受計算資源約束地去擴展。這對于Level 2中應用程序可以運行在不同云基礎設施上的能力來說至關重要。這里將計算和存儲解耦,不僅僅指服務所消費和管理的數據存儲,還包括log和配置數據等各種存儲機制。

成熟度2:抽象級

該層次引入應用程序可以運行在不同云計算基礎設施上的能力。這是個挑戰,因為現今主要的云計算平臺對于相同服務的接口和相同虛機鏡像的格式都是不同的。這限制了云計算應用程序可以在不同云提供商的平臺上運行遷移。工程師必須實現一層云隔離抽象層,使得應用程序實例可以運行在任何虛擬化基礎設施上且功能正常。這是個額外的工作,需要仔細評估成本/受益。這項工作帶來的收益是應用程序不再和供應商的特定接口綁定,避免了供應商鎖定,為運行時服務遷移提供了可能性。

除了與基礎設施解耦,Level 2級別的應用程序不應該依賴特定的服務實例的有效性,完全和其它服務的故障是隔離的。應用程序和它們的用戶對于應用程序的組件故障是無感知的,一種實現的方式是采用Netflix在基于亞馬遜云計算平臺上實現的電路開關(Circuit Breaker)設計模式。

最后,因為服務實例隨時可能故障,所以其它實例要能夠啟動并替代故障實例。這可以通過設計無狀態服務來實現。

成熟度3:自適應級

Level 3 表示應用程序被設計得充分符合云計算環境的特有特征。這一層次的應用程序可以部分或者全部地從一個云環境無縫地遷移到另一個云環境,沒有任何服務的中斷。這要求它們具備所有前一級成熟度的能力要求。云中的某種“主控程序”可以控制應用程序的編排和遷移,決定何時將應用程序遷移到何地。例如,應用程序可以將一部分從一個云環境遷移到另一個云環境中以便降低在高峰值負載時的資源租賃成本或者由于環境不穩定帶來的服務質量退化。

Level 3 級別的應用程序可以充分利用云的彈性和可擴展性,根據負載動態的實例伸縮。應用程序可以通過增加實例水平擴展,也可以通過增加虛擬CPU或者內存縱向擴展。應用程序需要提供元數據,使得基礎設施可以對特定服務的擴展做出合適決定。

運維策略

本節包含云計算應用程序的關鍵運維策略。運維策略指應用程序如何部署和操作,以及與別的系統組件進行交互。運維策略重點關注整系統全生命周期端到端的使用過程。

確保冗余

應用程序組件、虛機、網絡、存儲以及其它云基礎設計都有可能發生故障。在運維時考慮冗余,可以降低這些故障帶來的影響。例如,如果云環境部署在多個地理地區,應用程序和它依賴的組件可以在多個地區進行冗余,如果某一個地區發生了故障,業務可以被重鏡像到正常的區域,保證了業務的持續性。

使用緩存

緩存是一個在傳統系統以及基于云環境的系統中都廣泛使用的技術。通過將服務經常使用的數據在服務本地緩存可以提高系統性能,同樣可以提高容錯性,降低網絡帶寬消耗。當云服務提供商針對網絡帶寬統計計費時,緩存可以節省運維成本。

安全訪問API

安全API訪問保證應用和服務只被有權限的客戶端進行訪問。如早先解釋的,不能保證部署在云上的服務是安全的。一個解決方法是在每個服務前面加設一個API管理代理。這不僅僅用來限制訪問,還可以認證以及記錄API被哪些客戶端如何使用。Netflix使用這種方法限制核心共享服務的訪問。利用這種方式,Netflix確保服務訪問層僅僅路由自己開發的組件發送的請求。

分階段部署

在大的分布式系統中,軟件升級可能因為bug、副作用或者未預見的兼容性問題導致不可知的問題。當系統變得更大、更動態以及更復雜,更需要減少這類事情的發生。在敏捷開發實踐中,不同團隊更小更頻繁地發布也會增加這種風險。

一種控制風險的方式是小范圍的升級并且仔細監控新版本的行為。新和舊的版本并存,避免新版本搞掛整個系統。如果小范圍的部署成功,則可以在更大范圍內部署新實例的虛機,同時老版本的虛機繼續運行以支持容錯。如果新的版本失敗了,則請求被簡單地重鏡像到老版本實例上。如果新的版本最終一切成功,則老版本的虛機實例可以被關閉下線。

預防區域性故障

按照區域將云資源進行分組,每個區域獨立并與其它區域故障隔離。亞馬遜就將其EC2按照地理位置進行了區域劃分。從亞馬遜的云服務中斷歷史可以看出,中斷往往會影響整個地區。因此有必要在云應用部署時考慮彈性以避免區域性的故障。例如,Netflix將其全部服務在不同區域進行冗余,如果一個區域故障了,另一個區域可以接管失敗的區域繼續處理業務。這需要數據進行跨區域的同步。

應用程序在區域間可以部署成主備或者雙活模式。主備模式下,應用程序的實例在兩個區域都運行,但是只有一個處于激活態,一個全局的負載均衡器負責決定將客戶請求發送到哪一個處理點。

在雙活模式下,部署在兩個位置的應用程序都處于激活態,同時運行,處理不同用戶的請求。如果一個地區故障了,全局負載均衡器負責將所有負載重鏡像到仍然正常的區域。雙活模式提高了云資源的利用率,并且可以由離用戶較近的服務處理相應用戶的請求。

減少區域間時延

如果云環境地理位置分布較遠,或者一個數據中心被分割到多個區域,網絡延遲將會成為一個關鍵因素。

對于需要低時延的服務,盡量將它們部署在同一區域。一個挑戰是云上部署的應用程序并不知道其物理位置。仔細地對數據進行分析可以洞察一些應用在云中的物理位置特征,但是要知道,這些會隨著時間發生變化,超出應用所有者的控制。

高帶寬消耗服務云外部署

考慮將數據存儲到哪里可以降低數據傳輸開銷。例如,亞馬遜對于EC2和外部公共網絡間的數據傳輸進行計費。對于某些應用程序,這筆開銷可能會非常昂貴。將數據存儲在云外,例如CDN上,可以大大降低成本。

對依賴進行抽象

避免建立客戶和服務間的靜態依賴。例如,應用程序可能依賴于存儲服務,但是隨著時間推移,接口、實現以及存儲服務的位置都可能發生變化。例如應用程序可能遷移到一個新的云服務提供商,它的等價基礎設施服務的接口以及地址等都不同。對API進行管理,對底層服務的實現進行抽象,或者采用更加松耦合的REST API,可以讓組件彼此獨立地進行演進。

總結

當技術持續快速演進,開發者需要持續地提升自己的技能 - 學習以及采用新的技術來進行架構設計和開發,以構建更加魯邦的云應用程序。為了成功的提升云應用的能力,組織需要做如下事情:

  • 為員工的開發能力培訓進行投資,確保員工掌握構建云計算應用程序的技巧。
  • 找出辦法,避免開發人員浪費大量時間從事低層次、低價值的技術活動。
  • 發布的大規模復雜應用應該是易于修改且可以容易和已有系統進行集成的。

對開發者的建議

由于云計算領域特有的特征,應用程序開發者需要掌握建立分布式系統的設計原則和新的設計模式。這些原則和模式幫助云應用程序具備彈性擴展、高容錯、以及更有效地進行資源利用。

本文描述的策略主要針對分布式系統的內在挑戰。這些設計模式都是在大規模云應用程序中被開發人員證明是有效的。毫無疑問,當開發人員面臨新的云環境挑戰,為了更優雅的處理這些問題,他們會持續地創造出新的設計模式。

云應用成熟度模型則為開發者提供了評估他們云應用成熟度的標準,這可以為云應用程序云成熟度演進做決策。

云平臺需求

以下需求提給云計算提供商:

  • 支持云計算的行業標準,最好是開發標準或者是被廣泛支持的事實標準。這些支持可以防止應用程序鎖定到特定的云供應商,以及讓應用程序容易地在混合云環境中無縫運行。
  • 提供標準的鏡像,和其它云計算平臺所提供的鏡像保持一致。例如要開發一個私有云,考慮創建的鏡像和亞馬遜EC2提供的鏡像一致,如果應用程序有計劃未來一部分移植到亞馬遜的云平臺上。
  • 支持數據的親和性(支持數據的生產/消費者模式)。
  • 使用標準的版本控制腳本去創建和配置虛擬機。

我們正處于一個由云計算引起的重大技術變革中,促進開發者和企業進入一個真正的分布式技術的世界。技術人員有機會通過采用新的方法和技術開發適應云計算特點的應用程序,提供業務轉型的真正價值。ODCA(OPEN DATA CENTER ALLIANCE)希望本文為學習和研究面向云計算的應用程序架構技術的開發人員提供起點。ODCA認為提升開發人員的開發技能,以滿足不斷增長的云應用架構的軟件需求,需要持續地教育和培訓,使開發人員專注于技能發展以及工作領域的創新。

參考

附錄A:術語表

略。見原文!

附錄B:云計算反模式

云計算的反模式指一組應該被避免的在云上不好的設計實踐。下面列出的反模式限制了應用程序很好的發揮云計算的優勢:

  • 復雜配置。避免不必要的復雜繁瑣的配合設置。如果不需要熱插拔或者動態配置文件,就依靠持久配置。如果應用程序靠持久配置就可以,那么可以在持續集成環境將配置在應用程序編譯構建階段注入。這樣就避免了建立配置服務器的麻煩。不會出現所有的服務都去請求配置服務器造成配置服務器陷入拒絕服務狀態。
  • 復雜的依賴。避免應用程序依賴不必要的庫。這種依賴會導致應用程序過大從而使得鏈接、加載等過程變長。為了減少依賴,使用工具生成現有的依賴關系,只包括那些在應用程序部署到云中的所必須的依賴。
  • 管理共享狀態。避免在啟動時檢索應用程序的狀態,這會導致延遲從而讓應用程序不能快速地處理傳入的請求。

附錄C:安全訪問控制

訪問控制技術提供了一組限制系統訪問權限的配置機制?;诮巧目刂疲≧BAC)和基于特性的控制(ABAC)屬于云平臺上針對組件進行訪問控制的設計模式。

RBAC也稱為基于角色的安全。RBAC針對角色定制不同層級的權限。每個角色賦予一個和角色安全水平相關的訪問授權。反過來,角色和權限被分配給一個或者多個主題,一個主題可以是一個人或者自治的代理(例如一個自動提供創建和部署計算資源的服務)。

ABAC也稱為基于特性的安全。ABAC模型相對較新,結合了主題、策略以及屬性來定義一個邏輯訪問控制。這個邏輯定義允許用戶更容易地定義復雜的訪問控制策略。相反,RBAC則基于主題的當前狀態以及對應的角色,需要手動的更新策略。

附錄D:自動伸縮

自動伸縮控制計算資源的動態增加或者減少以匹配當前的負載。伸縮機制依賴于對負載的監控。監控使用高低門限(例如CPU利用率或者消息隊列長度)。當門限過高或者過低超過預定義的門限,則會引起告警以觸發彈性伸縮。

許多的商業和開源軟件提供了IaaS和PaaS層的自動彈性伸縮解決方案。每種解決方案的集成和自動化都不太一樣。以下是一些自動彈性伸縮的解決方案示例:

  • Amazon Auto Scaling
  • Azure Management Portal Scaler
  • Rackspace Auto Scale
  • Scalr
  • Eucalyptus Auto Scaling
  • RightScale Auto Scaling

附錄E:CAP理論

CAP理論由Eric Brewer提出,它說明一個分布式系統不可能同時滿足以下三個特性:

  • 一致性。通過任何節點的讀取都看到相同的數據(針對之前完成的寫入)。
  • 可用性。任何時候都可以成功讀寫(應答都有反應)。
  • 分區容錯性。隨意的消息丟失或者組件故障,系統都可以繼續運行(容錯性)。

當在云上實現一個數據存儲的時候,需要在可擴展性、性能和可靠性之間權衡。Brewer描述的這三個特性只能同時滿足兩個:CP、AP或者CA。

附錄F:數據庫分片

數據庫分片(Data sharding)是一種將數據庫中表按照行進行水平分區的設計原則。每個分片定義為一個shard。整個數據庫跨越多個分布的服務器,服務器之間沒有任何共享。數據庫分片可以提高數據庫的性能以及提高可擴展性。數據分片也提高了吞吐量以及數據庫的存儲容量。

“Sharding”這個詞產生于Google關于Bigtable的研究報告,“Bigtable: A Distributed Storage System for Structured Data”。

云計算應用程序因為依賴大規模的數據所以天然適合做sharding。數據分片減少了整體的客戶端延遲,提高擴展性和吞吐量。

附錄G:數據復制

數據復制指為數據存儲創建多個冗余版本。復制的數據需要在冗余資源之間保持一致性。數據復制提高了系統的可靠性,容錯性以及在數據源故障或者不可訪問時的數據可用性。如果數據源故障了,云應用可以平滑的切換到備份的數據源,保證了數據的一致性和可用性。

多份冗余的數據模型可以提供不一樣的持久化機制(例如:數據庫,磁盤存儲,或者文件存儲)。

附錄H:靜態內容托管

Web應用程序在處理動態頁面請求的時候會包含很多靜態內容??蛻舳讼螺d靜態內容會產生較多的負載。云應用應該將靜態內容和動態內容分離,將靜態內容分開存儲。

CDN(content delivery network,內容分發網絡)為靜態內容提供了地理上分布的存儲服務能力??蛻艨梢詮碾x自己近的CDN上獲取靜態內容,而云中只需要為客戶計算和發送動態內容。這樣可以提高整系統的吞吐量。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容