開(kāi)源驅(qū)動(dòng)12 Factor現(xiàn)代化項(xiàng)目
極具影響力的12 factor應(yīng)用方法論并未涵蓋許多近期的技術(shù)創(chuàng)新。Heroku 正在領(lǐng)導(dǎo)一項(xiàng)社區(qū)主導(dǎo)的努力,以使其保持最新。
譯自O(shè)pen Source Drives the Twelve-Factor Modernization Project,作者 Bob Reselman。
12 factor方法論是一套包含12個(gè)原則的體系,使公司能夠以統(tǒng)一且高度可管理的方式創(chuàng)建、運(yùn)行和維護(hù)企業(yè)級(jí)軟件即服務(wù) (SaaS) 應(yīng)用程序。12 factor方法論不依賴(lài)于任何特定產(chǎn)品、技術(shù)或工具集。相反,它是一種軟件開(kāi)發(fā)理念,其驅(qū)動(dòng)力是可移植性、彈性、穩(wěn)定性和成本效益。
12 factor應(yīng)用由Heroku聯(lián)合創(chuàng)始人Adam Wiggins于2011年創(chuàng)建,因此已經(jīng)存在一段時(shí)間了。多年來(lái),12 factor原則幫助開(kāi)發(fā)人員創(chuàng)建在云中運(yùn)行的更具彈性、更易于擴(kuò)展、管理和維護(hù)的應(yīng)用程序。
12 factor方法論首次出現(xiàn)時(shí),基于Web的應(yīng)用程序和Amazon Web Services仍處于起步階段。從那時(shí)起發(fā)生了很多變化,但12 factor方法論在很大程度上保持不變?,F(xiàn)在是將其現(xiàn)代化并使其與我們今天使用技術(shù)的方式保持一致的時(shí)候了,因此12 factor方法論已開(kāi)源。
在深入探討12 factor方法論開(kāi)源的目的和影響之前,我將首先介紹其背后的原則。
12 factor
以下是驅(qū)動(dòng)12 factor的原則的簡(jiǎn)要回顧,包括每個(gè)原則的含義以及如何使用它們。
Factor 1:代碼庫(kù)
含義:每個(gè)應(yīng)用使用一個(gè)代碼庫(kù),通過(guò)版本控制進(jìn)行跟蹤,并進(jìn)行多次部署。這確保所有與應(yīng)用程序相關(guān)的資產(chǎn)都在單個(gè)存儲(chǔ)庫(kù)中進(jìn)行管理。
應(yīng)用方式:通常,支持單個(gè)代碼庫(kù)意味著將項(xiàng)目的所有源代碼和輔助工件保存在單個(gè)源代碼存儲(chǔ)庫(kù)中,例如GitHub、BitBucket、AWS CodeCommit或Google CloudSource Repositories。代碼庫(kù)不應(yīng)散布在各種存儲(chǔ)庫(kù)中。
Factor 2:依賴(lài)
含義:明確聲明并隔離所有依賴(lài)項(xiàng),以避免隱式依賴(lài)于系統(tǒng)工具或庫(kù)。這使應(yīng)用程序更易于預(yù)測(cè)和管理。
應(yīng)用方式:支持依賴(lài)原則的關(guān)鍵是使用以受控方式存儲(chǔ)獨(dú)立庫(kù)和包的存儲(chǔ)庫(kù)。應(yīng)用程序應(yīng)將自定義代碼與獨(dú)立開(kāi)發(fā)的庫(kù)分開(kāi),并在配置文件中列出這些庫(kù)。然后,在運(yùn)行應(yīng)用程序時(shí),獨(dú)立庫(kù)會(huì)在構(gòu)建和運(yùn)行時(shí)添加到項(xiàng)目中。庫(kù)不與源代碼一起存儲(chǔ),而是存儲(chǔ)在由庫(kù)開(kāi)發(fā)者控制的單獨(dú)存儲(chǔ)庫(kù)中。
一些此類(lèi)存儲(chǔ)庫(kù)的示例包括npm(用于Node.js項(xiàng)目)、PyPI(用于Python)、MVN Repository(用于Java)、Chocolatey(用于.NET)和RubyGems(用于Ruby編程語(yǔ)言)。
Factor 3:配置
含義:將不同部署之間變化的任何配置與代碼分開(kāi)存儲(chǔ)。這允許您更輕松地進(jìn)行更改,而無(wú)需修改代碼庫(kù)。
應(yīng)用方式:將配置與代碼分離已成為企業(yè)系統(tǒng)架構(gòu)中的基本實(shí)踐。有時(shí),配置信息存儲(chǔ)在清單文件中。Kubernetes等框架會(huì)自動(dòng)將清單中聲明的信息注入環(huán)境中。此外,配置更新是通過(guò)更改清單文件中的信息來(lái)執(zhí)行的。框架會(huì)注意到更改并自動(dòng)更新環(huán)境。
配置要素有一個(gè)開(kāi)放的更新提案(issue #4)。
Factor 4:后端服務(wù)
含義:將后端服務(wù)(如數(shù)據(jù)庫(kù)、隊(duì)列和內(nèi)存緩存)視為附加資源,可以通過(guò)存儲(chǔ)在配置中的URL或其他定位器進(jìn)行訪問(wèn)。這使得服務(wù)易于互換。
應(yīng)用方式:該原則要求通過(guò)標(biāo)準(zhǔn)協(xié)議(例如HTTP/HTTPS連接)進(jìn)行資源訪問(wèn)。 理解使用庫(kù)和命令行界面 (CLI) 工具的關(guān)鍵在于,這些技術(shù)是對(duì)實(shí)際資源的抽象。它們與資源之間沒(méi)有緊密的綁定。程序員聲明對(duì)資源的訪問(wèn)憑據(jù)以及要執(zhí)行的操作。工具負(fù)責(zé)處理與資源交互的細(xì)節(jié)。
理論上,程序員應(yīng)該能夠以最小的影響從一個(gè)資源提供商切換到另一個(gè)資源提供商。但是,與任何技術(shù)一樣,魔鬼總是隱藏在細(xì)節(jié)中。因此,程序員應(yīng)該使用基于 TCP/IP 的資源。然后,代碼將被構(gòu)建為以通用的方式訪問(wèn)資源。
Factor 5:構(gòu)建、發(fā)布、運(yùn)行
含義:嚴(yán)格分離部署過(guò)程的構(gòu)建、發(fā)布和運(yùn)行階段。構(gòu)建階段編譯代碼,發(fā)布階段添加特定于環(huán)境的配置,運(yùn)行階段執(zhí)行應(yīng)用程序。
如何應(yīng)用:諸如 Jenkins 和 TeamCity 之類(lèi)的綜合 CI/CD 應(yīng)用程序可用于支持構(gòu)建、發(fā)布、運(yùn)行原則。這些工具通常允許程序員定義應(yīng)用程序的配置設(shè)置和源代碼存儲(chǔ)庫(kù)。這些工具具有腳本,可以自動(dòng)從指定的存儲(chǔ)庫(kù)獲取源代碼。然后,這些腳本構(gòu)建應(yīng)用程序并將配置設(shè)置應(yīng)用于測(cè)試代碼。(這些測(cè)試腳本與源代碼一起存儲(chǔ)在存儲(chǔ)庫(kù)中。)一旦構(gòu)建的代碼通過(guò)測(cè)試,腳本就會(huì)將構(gòu)建的應(yīng)用程序部署到指定的運(yùn)行時(shí)環(huán)境。CI/CD 工具與構(gòu)建、發(fā)布、運(yùn)行原則結(jié)合使用,允許持續(xù)快速、準(zhǔn)確且可觀察地部署應(yīng)用程序。
Factor 6:進(jìn)程
含義:將應(yīng)用程序作為一個(gè)或多個(gè)無(wú)狀態(tài)進(jìn)程執(zhí)行。持久性數(shù)據(jù)應(yīng)存儲(chǔ)在有狀態(tài)后端服務(wù)中。這使得擴(kuò)展更容易,并防止意外的副作用。
如何應(yīng)用:無(wú)狀態(tài)代碼是基于 Web 的應(yīng)用程序的基本原則。進(jìn)程唯一應(yīng)該做的是執(zhí)行處理邏輯。應(yīng)避免進(jìn)程之間的副作用;進(jìn)程不應(yīng)影響應(yīng)用程序的整體狀態(tài)或應(yīng)用程序中另一個(gè)進(jìn)程的狀態(tài)。要確定進(jìn)程的狀態(tài),請(qǐng)檢查獨(dú)立的真相來(lái)源,該來(lái)源協(xié)調(diào)所有進(jìn)程之間的活動(dòng)。
Factor 7:端口綁定
含義:使用端口綁定導(dǎo)出服務(wù),使其自包含并可通過(guò)指定的端口訪問(wèn)。
如何應(yīng)用:某些端口號(hào)已成為特定服務(wù)的象征。例如,非安全 Web 應(yīng)用程序的默認(rèn)端口是 80 端口。安全網(wǎng)站通過(guò) 443 端口上的 HTTPS 訪問(wèn)。Kafka 消息服務(wù)偵聽(tīng) 9092 端口上的客戶(hù)端流量。MySQL 數(shù)據(jù)庫(kù)的默認(rèn)端口是 3306。一些公司會(huì)不遺余力地將產(chǎn)品的品牌標(biāo)識(shí)與端口號(hào)關(guān)聯(lián)起來(lái)。Docker和Kubernetes使用端口聲明來(lái)定義域內(nèi)服務(wù)的訪問(wèn)點(diǎn)。在開(kāi)發(fā)級(jí)別,程序員通常根據(jù) localhost URL 在其機(jī)器上使用資源或服務(wù),然后通過(guò)關(guān)聯(lián)的端口號(hào)綁定到給定的資源或服務(wù)。
Factor 8:并發(fā)
含義:擴(kuò)展應(yīng)用程序時(shí),應(yīng)通過(guò)添加更多進(jìn)程來(lái)水平擴(kuò)展,而不是垂直擴(kuò)展單個(gè)進(jìn)程。
如何應(yīng)用:對(duì)按需水平擴(kuò)展的支持已成為現(xiàn)代 Web 規(guī)模企業(yè)應(yīng)用程序的關(guān)鍵功能。許多技術(shù),包括 AWS Elastic Container Service (ECS)、Docker Swarm、Google Cloud Run、Heroku、HashiCorpNomad 和 Kubernetes,都支持自動(dòng)擴(kuò)展。理解并發(fā)原則的關(guān)鍵在于,應(yīng)用程序必須由離散的、獨(dú)立的執(zhí)行邏輯單元組成,這些單元可以冗余地和同時(shí)運(yùn)行。運(yùn)行的單元數(shù)量可以根據(jù)當(dāng)前的流量需求進(jìn)行擴(kuò)展或縮減。
Factor 9:可丟棄性
含義:確??焖賳?dòng)和關(guān)閉時(shí)間,以最大限度地提高彈性和使系統(tǒng)更強(qiáng)大。
如何應(yīng)用:12 factor原則的可丟棄性原則體現(xiàn)了現(xiàn)代分布式應(yīng)用程序的短暫性。正如并發(fā)原則所指出的那樣,應(yīng)用程序?qū)⒁匀哂嗟姆绞絾?dòng)資源以滿足當(dāng)時(shí)的需要。因此,組件總是“來(lái)來(lái)去去”以滿足流量需求。 當(dāng)資源終止時(shí),必須快速且優(yōu)雅地進(jìn)行。這意味著確保沒(méi)有操作以無(wú)定形狀態(tài)終止。必須完成操作,必須關(guān)閉與外部資源的連接,并且必須安全地從內(nèi)存中刪除資源。組件終止后,應(yīng)用程序的整體狀態(tài)應(yīng)保持一致。
Factor 10:開(kāi)發(fā)/生產(chǎn)環(huán)境一致性
含義:保持開(kāi)發(fā)、登臺(tái)和生產(chǎn)環(huán)境盡可能相似,以促進(jìn)持續(xù)部署并減少開(kāi)發(fā)和生產(chǎn)之間的差距。
如何應(yīng)用:開(kāi)發(fā)/生產(chǎn)環(huán)境一致性原則類(lèi)似于構(gòu)建、發(fā)布、運(yùn)行原則,它將應(yīng)用程序開(kāi)發(fā)過(guò)程分解為離散的片段。但是,構(gòu)建、發(fā)布、運(yùn)行關(guān)注的是代碼發(fā)布,而開(kāi)發(fā)/生產(chǎn)環(huán)境一致性則關(guān)注跨升級(jí)開(kāi)發(fā)環(huán)境的代碼一致性。
通常,在軟件開(kāi)發(fā)的不同階段執(zhí)行不同的操作。在開(kāi)發(fā)階段,開(kāi)發(fā)人員提交代碼。該代碼會(huì)進(jìn)行代碼分析和單元(可能還有性能)測(cè)試。如果一切順利,它將被移至登臺(tái)環(huán)境。在登臺(tái)階段,代碼將接受更廣泛的測(cè)試制度,其中可能包括集成測(cè)試和滲透測(cè)試以查找安全風(fēng)險(xiǎn)。如果應(yīng)用程序?qū)⒂扇祟?lèi)使用,則登臺(tái)環(huán)境也是代碼進(jìn)行可用性測(cè)試以確保滿足人類(lèi)需求的地方。最后,成功后,代碼將在生產(chǎn)階段發(fā)布。
關(guān)于開(kāi)發(fā)/生產(chǎn)環(huán)境一致性的重要一點(diǎn)是,每個(gè)環(huán)境(開(kāi)發(fā)、登臺(tái)和生產(chǎn))必須相同,并且在每個(gè)環(huán)境中執(zhí)行自動(dòng)化工作時(shí)必須使用相同的工具。此外,除非是緊急更新,否則升級(jí)過(guò)程必須是單向的:代碼必須從開(kāi)發(fā)環(huán)境移動(dòng)到登臺(tái)環(huán)境,再到生產(chǎn)環(huán)境。不能來(lái)回移動(dòng)。并且,在緊急情況下,例如修補(bǔ)程序,當(dāng)代碼繞過(guò)開(kāi)發(fā)環(huán)境并直接從開(kāi)發(fā)人員的機(jī)器移動(dòng)到登臺(tái)環(huán)境時(shí),一旦修補(bǔ)程序代碼發(fā)布到生產(chǎn)環(huán)境,則必須更新開(kāi)發(fā)環(huán)境以適應(yīng)登臺(tái)環(huán)境中的更改。
在一個(gè)運(yùn)行良好的 IT 部門(mén)中,開(kāi)發(fā)人員的習(xí)慣是在本地機(jī)器上開(kāi)始編碼會(huì)話之前,每天檢查開(kāi)發(fā)環(huán)境的更新。這確保了任何緊急“向后”更新(在修補(bǔ)程序的情況下,從登臺(tái)環(huán)境到開(kāi)發(fā)環(huán)境)都會(huì)返回到開(kāi)發(fā)人員的機(jī)器。
開(kāi)發(fā)/生產(chǎn)環(huán)境一致性的關(guān)鍵因素是每個(gè)環(huán)境中基礎(chǔ)設(shè)施的統(tǒng)一性以及環(huán)境之間升級(jí)過(guò)程的可預(yù)測(cè)控制。
Factor 11:日志
含義:將日志視為事件流,并讓執(zhí)行環(huán)境聚合它們。這簡(jiǎn)化了日志管理和調(diào)試。
如何應(yīng)用:日志記錄應(yīng)通過(guò)將日志記錄事件視為獨(dú)立于任何特定技術(shù)的獨(dú)立數(shù)據(jù)流來(lái)完成。通常的實(shí)現(xiàn)是將日志事件視為一條消息,該消息由數(shù)據(jù)流技術(shù)(例如 Kafka)使用。將日志發(fā)射與日志存儲(chǔ)分離使應(yīng)用程序的可移植性更容易。
將日志記錄到數(shù)據(jù)流中會(huì)將存儲(chǔ)和數(shù)據(jù)管理的責(zé)任放在流管理技術(shù)上。權(quán)衡是關(guān)于發(fā)出日志數(shù)據(jù)的機(jī)器和應(yīng)用程序的信息變得不透明。因此,為了提高效率,使用標(biāo)準(zhǔn)化的消息格式至關(guān)重要。消息格式應(yīng)包含有關(guān)事件、機(jī)器、應(yīng)用程序以及與應(yīng)用程序操作相關(guān)的任何其他環(huán)境信息。
將日志記錄到事件流中有很多好處,但是您必須進(jìn)行額外的規(guī)劃以確保日志呈現(xiàn)準(zhǔn)確、全面且有用的信息。
此因素有一個(gè)開(kāi)放的提案,以擴(kuò)展它以反映當(dāng)前的可觀察性實(shí)踐,包括遙測(cè)(issue #3)。
Factor 12:管理流程
含義:將管理任務(wù)作為一次性流程運(yùn)行,在與應(yīng)用程序相同的代碼庫(kù)和版本控制系統(tǒng)中進(jìn)行管理。這確保了一致性和易于執(zhí)行。
如何應(yīng)用:應(yīng)用程序必須附帶其自身的管理功能,例如儀表板。例如,Substack(一個(gè)面向作家、記者和其他內(nèi)容創(chuàng)建者的在線出版平臺(tái))附帶一個(gè)儀表板功能,允許內(nèi)容創(chuàng)建者控制出版操作和讀者訪問(wèn)。該平臺(tái)還使內(nèi)容創(chuàng)建者能夠?yàn)楦顿M(fèi)訪問(wèn)細(xì)分某些內(nèi)容,并配置資金的收取方式。 此管理功能是Substack的一部分。它不是一個(gè)單獨(dú)的應(yīng)用程序,其源代碼也沒(méi)有托管在單獨(dú)的存儲(chǔ)庫(kù)中。通用應(yīng)用程序和管理流程都是統(tǒng)一代碼庫(kù)的一部分。Substack是管理流程原則的一個(gè)例子。重要的是要理解,管理功能是作為應(yīng)用程序的一部分進(jìn)行管理的,而不是作為與應(yīng)用程序分離的東西。
通過(guò)開(kāi)源邁向更高水平
您可能會(huì)從每個(gè)因素的描述中注意到的一件事是,12 factor方法對(duì)用于支持其原則的技術(shù)是不可知的。
當(dāng)12 factor應(yīng)用在2011年推出時(shí),這種方法論在技術(shù)領(lǐng)域是新思維。該原則的不可知性使得采用更容易,特別是對(duì)于像Heroku這樣的公司,它提供一個(gè)平臺(tái)可以支持各種各樣的工具和技術(shù)。然而,在接下來(lái)的幾年里,各種各樣的云提供商都采用了12 factor方法,并且通過(guò)使這種方法開(kāi)源,Heroku正在鼓勵(lì)社區(qū)幫助對(duì)其進(jìn)行現(xiàn)代化改造。
正如Heroku首席營(yíng)銷(xiāo)官在一次采訪中解釋的那樣:
“當(dāng)Adam Wiggins在14年前編寫(xiě)它時(shí),云計(jì)算仍然很新,Docker和Kubernetes還不存在。他正在為優(yōu)秀的SaaS應(yīng)該是什么樣子制定路線。從那時(shí)起,許多事情都發(fā)生了變化,修訂是必要的。但是,這不應(yīng)該僅僅是Heroku的觀點(diǎn)。許多云提供商和最終用戶(hù)組織都采用了12 factor原則。每一個(gè)都帶來(lái)了在云中大規(guī)模運(yùn)行這些類(lèi)型的應(yīng)用程序和基礎(chǔ)設(shè)施的不同經(jīng)驗(yàn)。他們的想法和貢獻(xiàn)需要被納入,以將12 factor提升到一個(gè)新的水平?!?/span>
正如Junod所指出的,推動(dòng)12 factor的原則在當(dāng)時(shí)是有意義的,但技術(shù)環(huán)境已經(jīng)發(fā)生了巨大的變化。它必須現(xiàn)代化,以解決遙測(cè)、身份驗(yàn)證和服務(wù)到服務(wù)(S2S)通信等問(wèn)題,現(xiàn)代開(kāi)發(fā)人員和架構(gòu)師每天都在處理這些問(wèn)題,但它們不是原始方法論的一部分。
為了鼓勵(lì)廣泛參與12 factor的現(xiàn)代化,11月,Heroku將其項(xiàng)目開(kāi)源,采用CC-BY-4.0許可證。該公司已將其12 factor的源代碼從其原始網(wǎng)站遷移到一個(gè)新的開(kāi)源存儲(chǔ)庫(kù)。
新的存儲(chǔ)庫(kù)為對(duì)12 factor的貢獻(xiàn)提供了一個(gè)中心活動(dòng)點(diǎn)。它包含更新版本的網(wǎng)站代碼和文檔,其中包含對(duì)這些因素更深入的描述。該存儲(chǔ)庫(kù)還包含來(lái)自各個(gè)組織的新思想和附加文檔的鏈接,包括O’Reilly、Nginx和IBM。這些公司秉承了12 factor的精神,他們的觀點(diǎn)對(duì)于使其在今天更實(shí)用非常寶貴。
開(kāi)源的兩個(gè)最重要的優(yōu)點(diǎn)是透明度和促進(jìn)基于社區(qū)的技術(shù)創(chuàng)新的機(jī)制。Heroku首席架構(gòu)師兼12 factor存儲(chǔ)庫(kù)維護(hù)者在12 factorDiscord服務(wù)器上的最近討論中表示,除了拓寬12 factor的范圍外,這種創(chuàng)新有望激發(fā)基于該方法論創(chuàng)建應(yīng)用程序的工具。
訣竅是使基于12 factor的應(yīng)用程序開(kāi)發(fā)成為一種全面統(tǒng)一的體驗(yàn)。開(kāi)源該項(xiàng)目和推動(dòng)12 factor的思想是朝著構(gòu)建彈性、可擴(kuò)展和可維護(hù)的、在網(wǎng)絡(luò)規(guī)模上運(yùn)行的應(yīng)用程序邁出的重要一步。
參與其中
12 factor軟件開(kāi)發(fā)方法已經(jīng)激發(fā)了十多年來(lái)的軟件開(kāi)發(fā)和架構(gòu)。其原則定義了一種統(tǒng)一、可預(yù)測(cè)的方式,使企業(yè)系統(tǒng)更安全地部署和更容易維護(hù)。
但是,鑒于過(guò)去十年發(fā)生的巨大技術(shù)變革,12 factor需要不斷發(fā)展以適應(yīng)時(shí)代。希望通過(guò)將12 factor作為一個(gè)開(kāi)源項(xiàng)目,更廣泛的貢獻(xiàn)者將帶來(lái)各種各樣的觀點(diǎn),這將有助于使12 factor在今天像2011年首次發(fā)布時(shí)一樣有用。






























