十二因子應用程序

參考 http://www.the12factorapp.com/

 “十二因子應用程序”源自於Heroku開發團隊在收集及觀察大量的SaaS(Software as a Service)應用程序開發和執行過程後,所整理出來的十二條開發SaaS應用程序時的方針。

    遵守這些方針可以增進應用程序本身的穩定性及擴充性,從程序開發到系統上線過程也會快捷很多。


1. 基準代碼(codebase):

    一對一的程序代碼版本管理

    "十二因子"的程序必須存儲在版本管理系統中,比如git,svn。程序代碼和應用應該以“一對一”的關係存儲:

  • 如果你的系統需要有多個代碼管理系統,那麼你的系統就是個分散式系統(Distributed System),分散式系統由多個應用程序組成,而這些應用程序都應分別套用“十二因子”。

  • “十二因子”反對一套程序的原代碼有多個應用程序在使用。如果需要分享部分的程序代碼,正確的解決方式應該是把共享的程序代碼封裝成庫(library,例如java的jar包),然後有需要的其他應用程序以“依賴性”程序庫來使用。

        每個“十二因子應用程序”都有屬於它專屬的程序代碼,透過專有的源代碼版本管理,可以清楚的安裝在不同的環境。也許每個環境有不同的版本,但每個系統所擁有的源代碼還是非常清楚乾淨的。有問題出現時,也可以簡單的回溯到之前的版本。

2. 依賴 (dependencies)

    明確定義所有依賴的程序庫

    “十二因子”要求應用程序必須使用依賴關係管理系統,比如java中的maven,或是ruby的rubygems,而且所有的第三方類庫必須明確定義出來,即使有些來自系統的程序庫也應列出來管理。這樣一來當新的工程師加入開發時,隨時都可以通過該管理系統簡單的安裝設置自己的開發環境,無論任務平臺都不會有衝突。

    一般來說容易被疏忽的部分是系統本身的程序庫或工具,“十二因子應用程序”必須將這些有相依賴性的程序以第三方程序庫的方式安裝,以避免應用程序被安裝在不支持的系統上。例如linux的curl command如果直接在程序碼裏使用,那這個應用程序就不能輕易的安裝在windows環境中。

3. 配置 (Config)

    將配置存儲在環境變量中

    配置(config)所指的是每個應用軟件在不同的安裝環境會設定的不同的參數。

    一般常見的例子:

  • 數據庫連接設置,例如URL,用戶,密碼。

  • 第三方服務的連接設定,例如微信 API的URL,帳號,密碼等。

    “十二因子應用程序”反對將這些配置變量存儲在原始代碼裏,建議把所有的配置都存儲在環境變量中。將配置變量存儲在原始中會有安全性的問題,一但程序代碼開發給其它團隊或個人時,這些機密的帳號密碼也容易不小心外露。另外配置參數是隨着環境在改變的,而應用程序的代碼跟版本的關係是固定的,同版本的應用程序在任務安裝的環境都是一樣的,所以配置參數需要另外管理。一般來說要個別定義在服務器的環境變量中,如此也可以改善應用程序的擴充性(Scalability)。

4. 後端服務 (Backing Services)

    所有後端支持系統都應視爲外接的資源

    所謂後端支持服務是指應用程序通過網絡傳輸得到的服務,例如數據庫,SMTP,緩存,API(微信公共號API)之類的的服務。

    負責管理這些支持服務的種類主要有本地的(local)跟第三方(3rd party),例如數據庫通常是同公司的系統工程師在管理,但如果主機架在雲端,大多數服務就都是通過第三方提供的了。“十二因子”的程序對待所有這些服務的種類必須是一致的。同一類後端服務都使用一樣的程序代碼來處理。唯一不同的地方只有連接用到的參數,如url,密碼,用戶,這些參數通過Config來管理。

    通過程序代碼一致,“十二因子應用程序”可以簡單的切換提供服務的來源。例如:如果要把mysql提供者從本地換到阿里雲,只要改連結的配置

5. 構建,發佈,運行 

    明確分離構建和運行的階段,使用工具 

    應用程序從代碼到發行/執行可以分爲以下三個階段:

    第一階段:構建(build),指通過構建系統將程序代碼及依賴包封裝起來。例如java程序打包成jar或是war包。

    第二階段:發行(release),將打包好的程序庫,加上環境配置通過發行管理系統上傳到要執行的環境裏,一般來說發行管理系統的另一個主要工作是將每個發行版本號的編碼規範定義好。每個不同版本的程序都應有對應的發行版本,版本定義可以用日期(2016-01-01 11:59:01)或是漸進的數字(v1.1.3)。

    第三階段:執行(run),所指的是發行的版本(包含程序包+配置),在該環境中執行。

    “十二因子應用程序"強調這三個階段必須清楚地分開並定義好。例如在執行階段不可以有任何的程序代碼改變。如果這三個階段可以分別設定好,應用程序就可以進入自動化的發行與執行,工程師開發新的功能,構建系統自動包裝,發行系統自動定義版本,然後新版本的應用程序跟配置一起發行到執行的環境中。出問題時也可以在發行中系統中選擇之前的版本回退回去。

6. 進程(Processes) 

    應用程序必須以“無狀態”的方式在進程上執行

    一般應用程序會在一個或多個進程中執行,例如在工程師的本地開發環境通常會用一個進程,而正式上線時系統通常會有多個進程來執行。

    “無狀態”指的是應用程序不會預設任務的狀態,每個request在執行完後,執行過程中所用到的狀態都不會被存儲下來。

    執行“十二因子應用程序”進程絕對是“元狀態”且不直接分享信息的,每個進程之間不會有任何的溝通,也不會預設互通的狀態。有需要互通的信息一律由後端支持服務存儲,例如數據庫或獨立緩存(如redis)。因爲應用程序會由多個進程執行,而無法預期下個request來時會由哪個進程執行,所以只有通過共用的後端服務纔可以確保狀態信息的完整性。

    另外,應用程序可以在上線的狀態下可以隨時增加進程甚至是新的服務器,如果應用是有狀態 的,則無法保證執行所需信息的完整性。例如常見的http sesion,就不應用直接存儲在內存裏,而應該利用可設置自動失效的memcached或是redis來存儲。

7. 端口綁定(port binding)

    通過端口綁定提供服務

    “十二因子應用程序”的服務一律都已經完整定義在程序代碼中了,要對外提供服務時,只要網絡服務器通過端口綁定就可以執行。例如一般的java web程序通常是通過tomcat或jetty之類的服務器,將連接綁定在8080上,對外就可以通過對外路徑設定路由到該應用程序上。如在本地一般就是直接連接上http://localhost:8080/。一個常見的例子就是一個服務器同時有客戶使用的應用程序和管理者使用的應用程序,只是綁定在不同的端口上了。 

    端口綁定的應用不只限於web程序,也可以是各種的網絡服務,例如ftp,或是種定製的服務。“十二因子應用程序”也可以成爲其他應用程序的“後端支持服務”,例如很多應用程序本生的服務只提供Restful API,而沒有任何界面。

8. 併發 

    通過併發進行擴展

    一般程序的執行環境都支持使用多個處理序列來執行應用程序,例如java的jvm就是通過線程讓軟件同步執行多個任務。

    “十二因子應用程序”利用這些同步執行的能力來增加應用程序的效率和擴充性。例如http requet由一個處理序列執行,需要定期執行的作業由另一個處理序列執行。

     這樣的設計配合“十二因子”中的無狀態跟不直接分享執行資源的原則,應用程序則可以簡單的通過增加硬件資源或雲端上的執行單元來最佳化執行的效率。

9. 快速啓用與終止(disposability)

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

    "十二因子應用程序”在開發的任何階段,都要確保程序的啓動速度要快,同時要確保程序終止時不會無法恢復或丟失重要數據的狀況。如果可以保持這兩個原則,應用程序本身就可以簡單的達到擴充性,或者是硬件遷移的過程也會簡化很多。

    應用程序在終止時要確認資料跟作業的完整度,通過後端支持服務來分享狀態,這樣當一個處理序列終止後,其他執行中的處理序列可以接着完成作業。例如有些程序有很多在後臺執行的程序,可以通過queuing service(例如rabbitmq)來分配要執行的工作,而無論哪個處理序列都可以分別執行,這樣單個應用程序纔可以安全的終止服務。 

10. 環境的一致性(Dev/Prod Parity)

    保持不同環境(dev,qa,staging,production)的一致性

    傳統應用軟件的開發環境(dev)通常會跟production生產環境不同,通常原因可能是資源跟人員的分配的差異性。這種差異性會造成三個軟件開發的落差:

  •     時間:從工程師的軟件開發環境到可以發行到生產環境需要很長的時間,有時需要幾周甚至幾個月才能發行新的版本。

  •     人力資源:軟件工程師負責開發軟件,需要通過系統工程師來發行軟件到生產環境。

  •     工具:軟件工程師在開發時使用較輕便的工具,而生產環境則使用功能完整的工具。例如工程師使用sqllit開發,而生產環境用mysql。

    “十二因子應用程序”強調“不間斷的發行環境”,發行的環境設定一律自動化,測試過的新功能要自動打包成新自動本,有時一天發行一個版本,有時甚至可以一天發行多個版本。

    另外“十二因子應用程序”強調任務環境都應用使用相同的工具或後端支持服務,例如數據庫或緩存。如果工具不同,會發生新版本在開發環境測試都通過了,但發行到生產環境就出問題的情況。如果真正要確保“不間斷髮行”的穩定性,就要儘量達到在各環境都使用與生產環境一樣的工具或後端服務。

    遵守”十二因子“的原則,則應用程序開發的環境就會穩定很多,且之前提到的落差就會減低:

  •     時間:從開發到發行時間減爲一天內。

  •     人力資源:發行環境設置好後,軟件工程師就可以自行發行新版本,不需要通過系統工程師。

  •     工具:任何環境的工具都與生產環境的一樣。

11. 日誌 

    通過外接服務將日誌整合起來

    應用程序的執行過程通常都是通過日誌記錄存儲起來的,一般的存儲方式爲將日誌寫在服務器的文件中,一旦日誌文件開啓後,應用程序的執行內容就會一行一行的寫在文件內,在程序終止前都會不斷的記錄着程序開發者認爲重要的信息,例如錯誤信息或是未來可以用來分析的信息。由於saas的應用程序通過會在多個主機上執行,這就造成日誌文件可能處於不連續的狀態,所以需要額外的服務來將這些日誌記錄整合起來。

    “十二因子應用程序”本身不管理任何關於整合記錄的服務,將這類整合的任務交給執行環境去處理。“十二因子”只負責將記錄寫入該執行環境的日誌文件中。

    目前已經有很多整合日誌的工具(例如logplex或是fluent),這些工具可以將每個主機上的日誌傳輸到一個服務器上,將每個記錄的內容依據發生時間整合起來,提供未來除錯或是分析使用。

12. 管理過程(Admin Processes)

    在相同環境下執行管理任務

    應用程序在上線一段時間後,難免需要執行一些管理任務,例如數據庫遷移,或是需要登錄控制檯之類的界面管理系統。有時候工程師爲了方便,在本地環境執行更新其他環境的工作,這樣的結果會造成應用程序本身的不穩定,且嚴重影響程序代碼版本的一致性。

    “十二因子應用程序”的管理相關任務必須跟程序本身在同一個環境執行,例如在qa的環境執行aq的管理任務,生產環境的管理任務就在生產環境執行。關於管理相關任務的程序代碼必須跟應用程序本身的代碼以同一個版本發行到該環境,配合該環境的配置參數來執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章