Saas 應用12個架構規範

JFrog傑蛙科技發表於2020-01-21

一、引言

如今,軟體通常會作為一種服務來交付,它們被稱為網路應用程式,或軟體即服務( SaaS)。 12-Factor 為構建如下的 SaaS 應用提供了方法論:

  • 使用 標準化流程自動配置,從而使新的開發者花費最少的學習成本加入這個專案。
  • 和作業系統之間儘可能的 劃清界限,在各個系統中提供 最大的可移植性
  • 適合 部署在現代的 雲端計算平臺,從而在伺服器和系統管理方面節省資源。
  • 將開發環境和生產環境的 差異降至最低,並使用 持續交付實施敏捷開發。
  • 可以在工具、架構和開發流程不發生明顯變化的前提下實現 擴充套件

這套理論適用於任意語言和後端服務(資料庫、訊息佇列、快取等)開發的應用程式。


二、特別宣告

本文轉自國外一篇文章,由Adam Wiggins所著,原文地址:

在此文基礎上增加個人的理解以及部分圖解。

 


三、十二個架構規範

1.統一原始碼管理系統


一份基準程式碼(Codebase),多份部署(deploy)

在類似 SVN 這樣的集中式版本控制系統中, 基準程式碼  就是指控制系統中的這一份程式碼庫;而在 Git 那樣的分散式版本控制系統中, 基準程式碼  則是指最上游的那份程式碼庫。

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

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

    

 


2.依賴管理

顯式宣告依賴

 

大多數程式語言都會提供一個打包系統,用來為各個類庫提供打包服務,就像 Perl    或是 Ruby    。透過打包系統安裝的類庫可以是系統級的(稱之為 “site packages”),或僅供某個應用程式使用,部署在相應的目錄中(稱之為 “vendoring” “bunding”

 

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

 

顯式宣告依賴的優點之一是為新進開發者簡化了環境配置流程。新的開發者可以檢出應用程式的基準程式碼,安裝程式語言環境和它對應的依賴管理工具,只需透過一個   構建命令  來安裝所有的依賴項,即可開始工作,如Maven,Pip,Npm等

 

12-Factor 應用同樣不會隱式依賴某些系統工具,如 ImageMagick 或是 curl。即使這些工具存在於幾乎所有系統,但終究無法保證所有未來的系統都能支援應用順利執行,或是能夠和應用相容。如果應用必須使用到某些系統工具,那麼這些工具應該被包含在應用之中。

 


3. 配置管理


在環境中儲存配置

 

通常,應用的   配置  在不同   (預釋出、生產環境、開發環境等等 )間會有很大差異。這其中包括:

Ø   資料庫, Memcached,以及其他  的配置

Ø   第三方服務的證照,憑證,如 Amazon S3Twitter

Ø   每份部署特有的配置,如域名等

 

應用程式不允許將配置儲存為程式碼中的常量,這需要 嚴格地將配置與程式碼分離。配置在部署之間差異很大,程式碼則沒有。另外, “config”的這個定義不包括內部應用程式配置,這種型別的配置在部署之間不會有所不同,因此最好在程式碼中儲存

 

提示:對應用程式是否在程式碼中正確分配了所有配置的試金石是,程式碼庫是否可以隨時變為開源,而不用擔心洩漏任何敏感憑據。

 

 

應用程式應將配置儲存在 環境變數中(通常縮寫為 env varsenv)。在不更改任何程式碼的情況下,可以在部署之間輕鬆更改 Env變數 與配置檔案不同,它們幾乎沒有機會被意外地檢入程式碼倉庫 與自定義配置檔案或其他配置機制(如 Java系統屬性)不同,它們是與語言和作業系統無關的標準。


 

 

 

 

4. 後端服務

把後端服務(backing services)當作附加資源

 

後端服務是指程式執行所需要的透過網路呼叫的各種服務,如資料庫( MySQL, ),訊息 /佇列系統( , ), SMTP 郵件傳送服務( ),以及快取系統( )。

 

類似資料庫的後端服務,通常由部署應用程式的系統管理員一起管理。除了本地服務之外,應用程式有可能使用了第三方釋出和管理的服務。示例包括 SMTP(例如   ),資料收集服務(例如      ),資料儲存服務(如   ),以及使用 API 訪問的服務(例如   Twitter Google Maps )。

 

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

12-Factor 應用將這些都視作   附加資源   ,這些資源和它們附屬的部署保持松耦合。

 

 


5. 構建,釋出,執行


嚴格分離構建和執行

 

轉化為一份部署 (非開發環境 )需要以下三個階段:

  • 構建階段  是指將程式碼倉庫轉化為可執行包的過程。構建時會使用指定版本的程式碼,獲取和打包   ,編譯成二進位制檔案和資原始檔。
  • 釋出階段  會將構建的結果和當前部署所需    相結合,並能夠立刻在執行環境中投入使用。
  • 執行階段  (或者說 執行時 )是指標對選定的釋出版本,在執行環境中啟動一系列應用程式  


12-factor 應用嚴格區分構建,釋出,執行這三個步驟。  舉例來說,直接修改處於執行狀態的程式碼是非常不可取的做法,因為這些修改很難再同步回構建步驟。

每一個釋出版本必須對應一個唯一的釋出 ID,例如可以使用釋出時的時間戳( 2011-04-06-20:32:17),亦或是一個增長的數字( v100)。釋出的版本就像一本只能追加的賬本,一旦釋出就不可修改,任何的變動都應該產生一個新的釋出版本。這樣也便於回退到任意歷史版本,而不需要冒風險重新構建。

 

新的程式碼在部署之前,需要開發人員觸發構建操作。但是,執行階段不一定需要人為觸發,而是可以自動進行。如伺服器重啟,或是程式管理器重啟了一個崩潰的程式。因此,執行階段應該保持儘可能少的模組,這樣假設半夜發生系統故障而開發人員又捉襟見肘也不會引起太大問題。構建階段是可以相對複雜一些的,因為錯誤資訊能夠立刻展示在開發人員面前,從而得到妥善處理。

 

 

6. 程式


以一個或多個無狀態程式執行應用

 

執行環境中,應用程式通常是以一個和多個   程式  執行的。

 

12-Factor 應用的程式必須無狀態且      任何需要持久化的資料都要儲存在    內,比如資料庫。

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

 

一些系統依賴於 , 這是指將使用者 session 中的資料快取至某程式的記憶體中,並將同一使用者的後續請求路由到同一個程式。粘性 session 12-Factor 極力反對的。 Session 中的資料應該儲存在諸如       這樣的帶有過期時間的快取中。

 


7. 埠繫結


透過埠繫結(Port binding)來提供服務

 

應用有時會執行於伺服器的容器之中。例如 PHP 經常作為    的一個模組來執行,正如 Java 執行於    

12-Factor 應用完全自我載入  而不依賴於任何網路伺服器就可以建立一個面向網路的服務。網際網路應用   透過埠繫結來提供服務  ,並監聽傳送至該埠的請求。

還要指出的是,埠繫結這種方式也意味著一個應用可以成為另外一個應用的   ,呼叫方將服務方提供的相應 URL 當作資源存入   以備將來呼叫。

 

 

8. 併發


透過程式模型進行擴充套件

 

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

 

上述程式模型會在系統急需擴充套件時大放異彩。  意味著新增併發會變得簡單而穩妥。這些程式的型別以及每個型別中程式的數量就被稱作   程式構成  

 

 

 


9. 易處理


快速啟動和優雅終止可最大化健壯性

 

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

 

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

 

另外程式   一旦接收     就會優雅的終止  。就網路程式而言,優雅終止是指停止監聽服務的埠,即拒絕所有新的請求,並繼續執行當前已接收的請求,然後退出。此型別的程式所隱含的要求是 HTTP請求大多都很短 (不會超過幾秒鐘 ),而在長時間輪詢中,客戶端在丟失連線後應該馬上嘗試重連;對於 worker 程式來說,優雅終止是指將當前任務退回佇列。

 

 


10. 開發環境與線上環境一致


儘可能的保持開發,預釋出,線上環境相同

 

開發環境(即開發人員的本地   )和線上環境(外部使用者訪問的真實部署)之間存在著很多差異。這些差異表現在以下三個方面:

  • 時間差異:  開發人員正在編寫的程式碼可能需要幾天,幾周,甚至幾個月才會上線。
  • 人員差異:  開發人員編寫程式碼,運維人員部署程式碼。
  • 工具差異:  開發人員或許使用 NginxSQLiteOS X,而線上環境使用 ApacheMySQL 以及 Linux

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

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

將上述總結變為一個表格如下:



傳統應用

12-Factor 應用

每次部署間隔

數週

幾小時

開發人員 vs 運維人員

不同的人

相同的人

開發環境 vs 線上環境

不同

儘量接近

 

12-Factor 應用的開發人員應該反對在不同環境間使用不同的後端服務  ,即使介面卡已經可以幾乎消除使用上的差異。這是因為,不同的後端服務意味著會突然出現的不相容,從而導致測試、預釋出都正常的程式碼線上上出現問題。這些錯誤會給持續部署帶來阻力。從應用程式的生命週期來看,消除這種阻力需要花費很大的代價。

 

 


11. 日誌


把日誌當作事件流

 

日誌  使得應用程式執行的動作變得透明。在基於伺服器的環境中,日誌通常被寫在硬碟的一個檔案裡,但這只是一種輸出格式。

 

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

在預釋出或線上部署中,每個程式的輸出流由執行環境截獲,並將其他輸出流整理在一起,然後一併傳送給一個或多個最終的處理程式,用於檢視或是長期存檔。這些存檔路徑對於應用來說不可見也不可配置,而是完全交給程式的執行環境管理。類似       的開源工具可以達到這個目的。

 

這些事件流可以輸出至檔案,或者在終端實時觀察。最重要的,輸出流可以傳送到    這樣的日誌索引及分析系統,或    這樣的通用資料儲存系統。這些系統為檢視應用的歷史活動提供了強大而靈活的功能,包括:

  • 找出過去一段時間特殊的事件。
  • 圖形化一個大規模的趨勢,比如每分鐘的請求量。
  • 根據使用者定義的條件實時觸發警報,比如每分鐘的報錯超過某個警戒線。

 



12. 管理程式


後臺管理任務當作一次性程式執行

 

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

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

一次性管理程式應該和正常的     使用同樣的環境。這些管理程式和任何其他的程式一樣使用相同的       ,基於某個     執行。後臺管理程式碼應該隨其他應用程式程式碼一起釋出,從而避免同步問題。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69954434/viewspace-2674106/,如需轉載,請註明出處,否則將追究法律責任。

相關文章