天天看點

The Twelve-Factor在Cloud Native時代是否依然适用?

按語

heroku是雲應用平台的先驅,從對外提供服務以來,他們已經有上百萬應用的托管和營運經驗。其創始人adam wiggins根據這些經驗,提出了十二要素應用宣言 。the twelve-factor app定義了一個優雅的網際網路應用在設計過程中,需要遵循的一些基本原則。

不過, the twelve-factor是在特定的時期,針對特定的平台實踐所總結出來的。12元素依然璀璨,很多原則依然具有普适性;但是在應用全面遷移到雲端的今天,cloud native時代的應用開發,需要有更多與時俱進的實踐新原則。the twelve-factor的哪些原則依然是适用的?哪些在實踐需要與時俱進?這些都是衆多cloud native的實踐者需要探求的答案。

新原則1:微服務應該以無狀态的方式運作

the twelve-factor指出一個應用在運作時,應該以一個或者多個無狀态的程序來運作。程序之間需要做到無狀态,并且無共享。任何需要持久化的資料,都應該寫入到後端服務中,譬如資料庫。這一原則,目的是避免程序和程序之間的耦合。讓每一個程序,能夠獨立于其他實體單獨建構和運作。

在很多線上系統中,會使用session(會話)來傳遞目前的狀态。當被調用方接收到session後,會将它儲存下來,後續的請求,都會被路由到這個服務中。這時請求和請求之間,會有嚴格的調用順序。cloud native的實踐原則是需要避免這種情況。

在cloud native理念中,每一個功能實體實際上是以一個微服務的形式運作的。微服務是一個單獨的自治系統,它可以不依賴其他服務而單獨存在。所有的微服務,都應該是以一種無狀态的接口對外提供服務(譬如restful api)。微服務自身不應該儲存任何的狀态。如果微服務需要持續地儲存資料,應該采用的做法是:調用服務化的存儲,将資料儲存在另一個存儲服務裡面。微服務之是以小塊頭能發揮大能量,正是源于無狀态的設計進而保證可以同時由多個執行個體提供服務,讓服務能力能夠自由的伸縮。

當然,在實際的實踐過程中,特别是針對大的系統,很難做到完全無狀态的拆分。對一個完整的微服務架構,會分為事務性服務和存儲型服務。通常說來,事務性服務需要做到無狀态設計;所有的持久化資料,可以通過存儲型服務來進行存儲和讀取。存儲型服務盡量使用雲端提供的集中式的服務化存儲能力,譬如雲端的對象存儲。

新原則2:應通過配置來唯一定義一個系統

the twelve-factor的第五條原則提到了應用需要嚴格區分建構、釋出、運作這三個步驟:譬如直接修改處于運作狀态的代碼是非常不可取的做法,因為這些修改很難再同步回建構步驟。the twelve-factor的第五原則,很好的規範了一個應用從開發到營運的标準化的操作流程。但是第五原則,隻是保證了應用源碼的唯一性。很多時候,一個系統的故障,并不僅僅是由源碼導緻的,很大一部分故障,和配置以及環境的變化存在關系。是以the twelve-factor的第五原則在cloud native的理念下,需要與時俱進。

cloud native在實踐時,是通過docker+微服務的方式去實作的。docker實作了build、ship、run的統一。任何系統,都是可以通過一些配置,唯一定義出來的。當這個系統定義出來以後,應該是能夠重構出來,不随着時間、運作環境或依賴條件變化而變化。同時,這個系統不管處于開發階段、測試階段還是營運階段,其狀态都是唯一的。

譬如,在實踐過程中,可以通過docker compose的yaml檔案唯一的定義一個容器間互聯的系統。這個系統的配置是唯一确定的,可以在任何的容器環境下去執行。會有一個唯一的倉庫(docker registry)來存儲鏡像。所有的鏡像,都是通過dockerfile唯一定義的。當觸發了源碼的變更以後,這個系統的各個元件可以自動的去建構,然後更新到“倉庫”,在通過docker compose組裝起來。隻要遵循了這套标準化的流程,系統不會區分開發環境,測試環境,營運環境。所有的東西,就隻有一個環境;這個環境,是唯一的、可定義的。

在實踐這條原則時,需要遵循以下幾條規範: 

需要有唯一的源碼庫,并保證任何的變更都是在源碼托管庫中進行 

通過dockerfile來建構鏡像而非通過運作中的容器來打包鏡像 

通過配置來定義容器之間的連接配接關系而非手動的部署

新原則3:應該使用服務化存儲

the twelve-factor 有一條原則是“把後端服務(backing services)當作附加資源”,後端服務是指程式運作所需要的通過網絡調用的各種服務,如資料庫(mysql,couchdb)、消息/隊列系統(rabbitmq,beanstalkd)、smtp 郵件發送服務(postfix)以及緩存系統(memcached)。這些都是作為“資源”來對待,目的是為了保證子產品之間的松耦合。

作為一個系統中最重要的角色,存儲子產品當然必不可少。存儲有很多種類:塊存儲、對象存儲、資料庫存儲、緩存。傳統上,我們接觸比較多的是塊存儲。在cloud native的理念下,一個系統中,所有的組成實體都可以服務化。有事務型的服務,也有存儲型服務。微服務之間是一種松散耦合的關系。服務和服務之間,是沒有任何耦合關系的,隻有調用關系。當一個服務,需要存儲資料怎麼辦?一種方案是把資料存在在服務内部,這樣勢必導緻了服務存在狀态,進而限制了服務的橫向擴充的能力。前面一節,我們提到了一個重要原則是,事務型服務盡量保證是無狀态的。是以當一個事務型服務需要存儲資料時,應該是将資料存儲到另外一個存儲型服務中,通過存儲型服務提供的标準接口和協定讀取或者寫入資料。在雲上我們通常使用的對象存儲,或者雲端的資料庫,就是這種服務化的存儲方式。

使用服務化存儲,可以帶來三個方面的好處: 

将存儲和邏輯處理分離,讓系統能夠自動化的重構出來 

統一存儲,不需要單獨考慮服務内部存儲的容錯、備份等機制 

做到事務型服務無狀态,便于橫向擴充

總結

the twelve-factor app作為網絡應用開發的最佳實踐原則,的确具有強大的生命力。每一條原則都是應用開發的珠玑。但是技術總是不停的發展,在雲的時代,所有的應用都會遷移到雲端,完全基于雲的架構設計和開發模式需要一套全新的理念去承載。這個時候,cloud native的思想應運而生。在cloud native時代,the twelve-factor 的核心思想依然璀璨,但是應該随着這種新的理念去延伸、發展。文章提到的三條新原則,也正是the twelve-factor 的延伸。未來,随着cloud native 思想在開發中使用越來越廣泛,一定會延伸出更多的實踐的原則。

資料附:cloud native時代12新要素

從一個代碼庫部署到多個環境——一個代碼庫,包括生産環境軟體包,確定了單一的信任源,進而保證了更少的配置錯誤和更強的容錯和複原能力。 依賴管理是聲明式的——雲平台根據這些聲明管理依賴,確定雲應用所需的庫和服務。 配置資訊儲存在環境中——環境變量是一種清楚、容易了解和标準化的配置方法,特别适合用不同程式設計語言編寫的無狀态應用的使用。 将背景服務視為附加的資源——将每一種資源都視為一種遠端的資源,應用是以具有容錯和複原能力,因為它一方面要求編碼時就要考慮資源不可用的情況,另外一方面也增強微服務方法的好處。 區分建構、釋出和運作階段——cloud native應用的建構流程把大部分釋出配置挪到開發階段,包括實際的代碼建構和運作應用所需的生産環境配置。 作為無狀态程序運作——盡量保持應用棧每一層的輕量級,保證cloud native基礎設施的速度和效率。 通過端口綁定對外暴露服務——cloud native應用的服務接口優先選擇 http api 作為通用的內建架構。 通過添加無狀态程序實作橫向擴充——強調無狀态、無共享的設計,這意味着依賴底層平台就能實作橫向擴充,不需要技術難度高的多線程編碼。 快速地啟動,優雅地關停——假設任何程序随時都能啟動和關停。 開發、預釋出和生産環境運作同樣的應用和依賴配置——由于強調自動化和在每個階段使用同一個雲平台,如果每個人用同樣的伺服器配置,那麼“應用在我這裡是可以的”就意味着在其他人或者環境那裡也是可以的。 日志輸出到标準輸出,友善日志聚合和事件響應——當日志是由雲平台而不是應用包含的庫處理時,日志處理機制必須保持簡單。 臨時任務作為短時程序運作——在cloud native中,管理任務也是一個程序,而不是特别的工具;同樣重要的是,管理任務的程序不應使用秘密的 api 或者内部機制。

作者簡介

劉永峰,騰訊雲進階産品經理,布道師,十餘年的産品及研發管理經驗。國内最早一批從事可信計算研究的探索者。曾就職于中興通訊,負責流媒體server背景架構設計,linux核心相關的研究。2011年起加入騰訊,一直從事公有雲的産品設計,雲計算市場趨勢分析和研究,雲計算技術的推廣與普及。在技術和産品領域均具有豐富的行業經驗。目前主要關注docker,微服務,cloud native, 企業雲化趨勢等相關領域。

====================================分割線================================

本文轉自d1net(轉載)