良好的雲原生應用設計需要考慮的15個因素

良好的雲原生應用設計需要考慮的15個因素

要開發雲原生的應用和服務,只把舊的單體應用打包到一個Docker鏡像然後把它放在Kubernates上運行是不夠的。要建設一個好的雲應用/服務,我們還需要遵循一定的原則,我們基於Heroku定義的《12因子應用》(https://12factor.net/zh_cn/build-release-run)優化出以下原則:

1 、一份基準代碼(Codebase),多份部署(deploy)

基準代碼和應用之間總是保持一一對應的關係:

  • 一旦有多個基準代碼,就不能稱為一個應用,而是一個分佈式系統。分佈式系統中的每一個組件都是一個應用,每一個應用可以分別使用 12-Factor 進行開發。
  • 多個應用共享一份基準代碼是有悖於 12-Factor 原則的。解決方案是將共享的代碼拆分為獨立的類庫,然後使用 依賴管理 策略去加載它們。

2 、 API 優先

為每個服務定義REST 和消息驅動API,並且每個服務都可以在組件文檔裡找到對應的規格說明。

每個協議都需要定義明確,以便支持各種不同的實現。支持不同實現方式的目標是使我們可以支持更廣泛的場景。

3、依賴管理

顯式聲明依賴關係,12-Factor規則下的應用程序不會隱式依賴系統級的類庫。 它一定通過 依賴清單 ,確切地聲明所有依賴項。此外,在運行過程中通過 依賴隔離 工具來確保程序不會調用系統中存在但清單中未聲明的依賴項。這一做法會統一應用到生產和開發環境。

4、設計、構建、發佈、運行

12-factor 應用嚴格區分構建,發佈,運行這三個步驟。

舉例來說,直接修改處於運行狀態的代碼是非常不可取的做法,因為這些修改很難再同步回構建步驟。

部署工具通常都提供了發佈管理工具,最引人注目的功能是退回至較舊的發佈版本。比如, Capistrano 將所有發佈版本都存儲在一個叫 releases 的子目錄中,當前的在線版本只需映射至對應的目錄即可。該工具的 rollback 命令可以很容易地實現回退版本的功能。

每一個發佈版本必須對應一個唯一的發佈 ID,例如可以使用發佈時的時間戳(2011-04-06-20:32:17),亦或是一個增長的數字(v100)。發佈的版本就像一本只能追加的賬本,一旦發佈就不可修改,任何的變動都應該產生一個新的發佈版本

5、配置、憑據和代碼

使用"配置中心"來統一管理所有服務的環境變量和配置信息。這些配置信息可以用環境來區分,用Kubernetes的Secrets來整合其他Secret提供方來管理憑據。

6、日誌

日誌應該是 事件流 的彙總,將所有運行中進程和後端服務的輸出流按照時間順序收集起來。儘管在回溯問題時可能需要看很多行,日誌最原始的格式確實是一個事件一行。日誌沒有確定開始和結束,但隨著應用在運行會持續的增加。

12-factor應用本身從不考慮存儲自己的輸出流。 不應該試圖去寫或者管理日誌文件。相反,每一個運行的進程都會直接的標準輸出(stdout)事件流。開發環境中,開發人員可以通過這些數據流,實時在終端看到應用的活動。

7、易處置

12-Factor 應用的 進程 是 易處理(disposable)的,意思是說它們可以瞬間開啟或停止 這有利於快速、彈性的伸縮應用,迅速部署變化的 代碼 或 配置 ,穩健的部署應用。

進程應當追求 最小啟動時間 。 理想狀態下,進程從敲下命令到真正啟動並等待請求的時間應該只需很短的時間。更少的啟動時間提供了更敏捷的 發佈 以及擴展過程,此外還增加了健壯性,因為進程管理器可以在授權情形下容易的將進程搬到新的物理機器上。

8、後端服務

12-Factor 應用不會區別對待本地或第三方服務 對應用程序而言,兩種都是附加資源,通過一個 url 或是其他存儲在 配置 中的服務定位/服務證書來獲取數據。12-Factor 應用的任意 部署 ,都應該可以在不進行任何代碼改動的情況下,將本地 MySQL 數據庫換成第三方服務(例如 Amazon RDS)。類似的,本地 SMTP 服務應該也可以和第三方 SMTP 服務(例如 Postmark )互換。上述 2 個例子中,僅需修改配置中的資源地址。

9 、環境一致

12-Factor 應用想要做到 持續部署 就必須縮小本地與線上差異 再回頭看上面所描述的三個差異:

  • 縮小時間差異:開發人員可以幾小時,甚至幾分鐘就部署代碼。
  • 縮小人員差異:開發人員不只要編寫代碼,更應該密切參與部署過程以及代碼在線上的表現。
  • 縮小工具差異:儘量保證開發環境以及線上環境的一致性。

10、管理進程

後臺管理任務當作一次性進程運行,進程構成(process formation)是指用來處理應用的常規業務(比如處理 web 請求)的一組進程。與此不同,開發人員經常希望執行一些管理或維護應用的一次性任務,例如:

  • 運行數據移植(Django 中的 manage.py migrate, Rails 中的 rake db:migrate)。
  • 運行一個控制檯(也被稱為 REPL shell),來執行一些代碼或是針對線上數據庫做一些檢查。大多數語言都通過解釋器提供了一個 REPL 工具(python 或 perl) ,或是其他命令(Ruby 使用 irb, Rails 使用 rails console)。
  • 運行一些提交到代碼倉庫的一次性腳本。

一次性管理進程應該和正常的 常駐進程 使用同樣的環境。這些管理進程和任何其他的進程一樣使用相同的 代碼 和 配置 ,基於某個 發佈版本 運行。後臺管理代碼應該隨其他應用程序代碼一起發佈,從而避免同步問題。

11、端口綁定

12-Factor 應用完全自我加載 而不依賴於任何網絡服務器就可以創建一個面向網絡的服務。互聯網應用 通過端口綁定來提供服務 ,並監聽發送至該端口的請求。

本地環境中,開發人員通過類似http://localhost:5000/的地址來訪問服務。在線上環境中,請求統一發送至公共域名而後路由至綁定了端口的網絡進程。

通常的實現思路是,將網絡服務器類庫通過 依賴聲明 載入應用。例如,Python 的 Tornado, Ruby 的Thin , Java 以及其他基於 JVM 語言的 Jetty。完全由 用戶端 ,確切的說應該是應用的代碼,發起請求。和運行環境約定好綁定的端口即可處理這些請求。

12 、無狀態進程

12-Factor 應用的進程必須無狀態且 無共享 任何需要持久化的數據都要存儲在 後端服務 內,比如數據庫。

內存區域或磁盤空間可以作為進程在做某種事務型操作時的緩存,例如下載一個很大的文件,對其操作並將結果寫入數據庫的過程。12-Factor應用根本不用考慮這些緩存的內容是不是可以保留給之後的請求來使用,這是因為應用啟動了多種類型的進程,將來的請求多半會由其他進程來服務。即使在只有一個進程的情形下,先前保存的數據(內存或文件系統中)也會因為重啟(如代碼部署、配置更改、或運行環境將進程調度至另一個物理區域執行)而丟失。

13 、併發

在 12-factor 應用中,進程是一等公民12-Factor 應用的進程主要借鑑於 unix 守護進程模型 。開發人員可以運用這個模型去設計應用架構,將不同的工作分配給不同的 進程類型 。例如,HTTP 請求可以交給 web 進程來處理,而常駐的後臺工作則交由 worker 進程負責。

這並不包括個別較為特殊的進程,例如通過虛擬機的線程處理併發的內部運算,或是使用諸如 EventMachine, Twisted, Node.js 的異步/事件觸發模型。但一臺獨立的虛擬機的擴展有瓶頸(垂直擴展),所以應用程序必須可以在多臺物理機器間跨進程工作。

上述進程模型會在系統急需擴展時大放異彩。 12-Factor 應用的進程所具備的無共享,水平分區的特性 意味著添加併發會變得簡單而穩妥。這些進程的類型以及每個類型中進程的數量就被稱作 進程構成 。

14、遠程監控

可遠程監控應用的健康指標,也提供業務級別的操作事件查詢。這些信息可以用於數據倉庫、報表和預測。

15、驗證和授權

需要為所有服務提供單點登錄、角色權限控制。


分享到:


相關文章: