閱讀筆記(十八)SAAS的奠基石12 factor-app《The Twelve-Factor App》

一. 前言

  12 factor app是SAAS(Software As A Service)的基本原則,也是在我們日常工作中需要遵循的原則。其原文鏈接在文末給出,因爲有對應的中文版(雖然翻譯的不是很好)所以本文主要不在於複製粘貼一遍內容,而是對其內容的歸納和理解,以及一些自己遇到的事例經驗。12 factor app核心思想包括:

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

下面詳細講解12個基本原則。

二. 12個基本原則和理解

  1. 基準代碼

  該部分主要有幾點注意事項

(1)版本控制工具的使用對於任何工程均十分重要,如Git, Mercurial, Subversion。這些工具是多個程序員協同完成一個產品必備的管理工具和記錄工具
(2)基準代碼和應用是一一對應的關係,不存在一對多或者多對一
(3)基準代碼可以部署爲很多不同的版本,舉個例子,遊戲有當前運行供給玩家的版本,有正在開發的新版本,有體服測試版本,有供給測試的版本等等等等。

  1. 依賴

  SAAS要求應用指明顯示依賴清單,並且不依賴清單外的任何庫。這條原則很容易理解:所有在Linux有過安裝應用缺依賴庫的都曾因此煩躁過。而採用這條原則的如如Ruby/Bundler 下使用 bundle install,而 Clojure/Leiningen 則是 lein deps,一條指令直接打包安裝無需煩惱,是多麼令人心情愉悅的事。

  1. 配置

  因爲一個基準代碼可能存在不同的部署,而不同的部署可能有着不同的配置,比如數據庫的使用,第三方證書,域名等等,因此需要考慮如何保證基準代碼和配置的隔離,即該應用的基準代碼是否可以立刻開源,而不用擔心會暴露任何敏感的信息。鑑於此,此處給出的推薦解決方法是將配置信息存儲於環境變量之中,從而實現在不同的部署中方便的修改又不需要因此修改基準代碼的內容。

  1. 後端服務

  該條原則要求代碼對使用何種後端服務不敏感,即解耦合或者鬆耦合,隨時修改後端的策略對用戶使用應用並沒有任何影響,該條原則可以說是後端開發必備原則了。將本地/第三方服務均視爲抽象的資源,資源的增刪修改對上層毫無影響。

  1. 構建、發佈和運行

  將基準代碼轉化爲商用部署需要嚴格執行這三個步驟:

  • 構建階段 是指將代碼倉庫轉化爲可執行包的過程。構建時會使用指定版本的代碼,獲取和打包 依賴項,編譯成二進制文件和資源文件。
  • 發佈階段 會將構建的結果和當前部署所需 配置 相結合,並能夠立刻在運行環境中投入使用。
  • 運行階段 (或者說“運行時”)是指針對選定的發佈版本,在執行環境中啓動一系列應用程序 進程。

  本條原則是商業化產品的標準開發路線,屬於通用的基本原則。

  1. 進程

  本條原則在於避免進程間通信或者資源共享。這樣做既是爲了安全考慮,也是爲了程序的高效和健壯性考慮。而所有需要使用的資源,統一交給後端存入硬盤和數據庫中實現。
  這一條其實存在一些爭議,對於微服務場景適用,但是對於一些其他應用不一定適用,不屬於通用原則。

  1. 端口綁定

  本條取名爲端口綁定其實不大恰當,其本意包括了兩點:(1)SAAS應用不應該依賴於任何其他網絡服務器,而是自己綁定端口運行 (2)互聯網應用 通過端口綁定來提供服務 ,並監聽發送至該端口的請求

  1. 併發

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

  本條原則建立在原則6的基礎上,由於這種特殊的架構,使得擴展性極佳,在微服務領域屬於最基本的原則。也可以借鑑於其他領域使用。

  1. 易處理

  本條原則要求代碼有着快速啓動和優雅終止的健壯性。首先,代碼的啓動時間應該儘可能地小,因此在出錯時可以快速地重啓,也更利於擴展性。其次,當收到終止信號SIGTERM時,則“優雅”的退出。這裏的“優雅”指的是:
(1)對網絡進程來說停止監聽端口,執行完當前任務後立刻停止工作
(2)對工作線程來說將當前任務退回隊列,例如,RabbitMQ 中,worker 可以發送一個NACK信號。 Beanstalkd 中,任務終止並退回隊列會在worker斷開時自動觸發。有鎖機制的系統諸如 Delayed Job 則需要確定釋放了系統資源。此類型的進程所隱含的要求是,任務都應該 可重複執行 , 這主要由將結果包裝進事務或是使重複操作 冪等 來實現。
(3)在意外死亡時,保持健壯。這裏推薦使用健壯的後端隊列,如Beanstalkd。

  1. 開發環境和線上環境等價

  實際上開發和線上環境存在差異是很正常的事,主要體現在:

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

爲了縮小差異,大致需求如下:

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

爲了實現這些,需要開發人員做到使用和線上一致的環境進行開發,而不是爲了方便使用輕量級應用。

  1. 日誌

  把日誌當作事件流,應用本身不考慮自己的輸出流,而是在此之外採用額外處理程序用於查看或長期存檔。這種做法的好處在於統一了日誌的處理,並單獨分離了功能,易於後續優化和修改。

  1. 管理進程

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

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

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

參考文獻

【1】https://12factor.net/

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