DevOps四大能力的建設(shè)需要實(shí)踐與工具進(jìn)行支撐玻孟,結(jié)合能力建設(shè)的要求唆缴,實(shí)踐主要分布在持續(xù)交付和技術(shù)運(yùn)營兩大領(lǐng)域,包括持續(xù)集成黍翎、持續(xù)部署面徽、微服務(wù)、自動(dòng)化監(jiān)控預(yù)警、灰度發(fā)布等等趟紊。本章重點(diǎn)介紹DevOps的實(shí)踐方法和相應(yīng)的工具氮双,以幫助大家解決具體的問題。
1. 實(shí)踐分布圖
圖 1:DevOps實(shí)踐分布圖
在交付過程的各個(gè)環(huán)節(jié)中分布著DevOps相關(guān)實(shí)踐霎匈,這些實(shí)踐的目的可以分為:提高速度和提高質(zhì)量戴差。如自動(dòng)化構(gòu)建、自動(dòng)化部署等都是為了更快交付铛嘱;單元測(cè)試暖释、代碼掃描、功能測(cè)試等都是為了交付更高質(zhì)量的代碼和服務(wù)墨吓。除了各個(gè)環(huán)節(jié)的實(shí)踐以外饭入,還有貫穿整個(gè)過程,和文化有關(guān)的肛真,比如自組織團(tuán)隊(duì)、持續(xù)改進(jìn)等爽航。
2. 實(shí)踐介紹2.1 代碼管理
分布式的工作模式
編寫代碼
提交代碼到本地版本庫
從服務(wù)器來回最新代碼蚓让,解決沖突
提交代碼到本地庫
將本地代碼推送到服務(wù)器
分支策略
圖 2:Git工作流圖
代碼管理規(guī)范
每個(gè)團(tuán)隊(duì)成員都頻繁提交到主干
使用意義明確的提交注釋
簡單的總結(jié)性描述(使用fix, add, change等關(guān)鍵字)
更多的細(xì)節(jié)
缺陷與任務(wù)系統(tǒng)的鏈接(UCM)
示例:Fix 用戶登錄失敗拋出異常的缺陷[Bug #2873942]原因分析:用戶登錄時(shí)會(huì)調(diào)用騰訊的開放用戶認(rèn)證平臺(tái),由于網(wǎng)絡(luò)不穩(wěn)定造成個(gè)別用戶登錄失敗讥珍,系統(tǒng)直接拋出程序異常錯(cuò)誤历极,影響用戶體驗(yàn)。解決辦法:在register_from_tencent方法中增加了異常處理衷佃,友好提示登錄失斕诵丁;已聯(lián)系技術(shù)運(yùn)營團(tuán)隊(duì)處理網(wǎng)絡(luò)不穩(wěn)定問題
每次開發(fā)新功能都可以新建一個(gè)單獨(dú)的分支
每次提交都應(yīng)該是原子性的氏义,即每次提交都有業(yè)務(wù)意義锄列,比如解決一個(gè)缺陷,新增一個(gè)特性等
2.2 Code Review
Code Review對(duì)保證代碼質(zhì)量和促進(jìn)團(tuán)隊(duì)學(xué)習(xí)交流都很有幫助惯悠,不建議組織定期的評(píng)審會(huì)議來進(jìn)行Code Review邻邮,原因如下:
無法做法事前控制,有問題的代碼已經(jīng)簽入代碼庫
評(píng)審會(huì)議中對(duì)代碼的覆蓋率不足克婶,容易漏掉潛在的問題
開發(fā)者需要回想需求和代碼實(shí)現(xiàn)過程筒严,成本高
此時(shí)對(duì)代碼的修改容易引發(fā)新問題
建議每次提交時(shí)都進(jìn)行強(qiáng)制的Code Review,通過高頻率情萤、小粒度的Review更有助于盡早發(fā)現(xiàn)問題鸭蛙,促進(jìn)團(tuán)隊(duì)交流協(xié)作。
Code Review是一種工程實(shí)踐筋岛,更是一種文化娶视,需要團(tuán)隊(duì)對(duì)代碼有較高的質(zhì)量要求和共識(shí)。
2.3 私有構(gòu)建
私有構(gòu)建(Private Build): 持續(xù)集成的實(shí)踐之一泉蝌,在每次提交代碼時(shí)執(zhí)行歇万,目的是盡快發(fā)現(xiàn)構(gòu)建錯(cuò)誤揩晴,保證代碼庫的可構(gòu)建狀態(tài)(可編譯、單元測(cè)試通過)以提供集成構(gòu)建成功率贪磺,其構(gòu)建范圍比集成構(gòu)建小硫兰,一般為當(dāng)前提交分支的代碼,要求構(gòu)建速度快寒锚,反饋及時(shí)劫映。
圖 3:私有構(gòu)建示意圖
2.4 集成構(gòu)建
集成構(gòu)建(Integration Build):持續(xù)集成的實(shí)踐之一,一種集成類型刹前,定時(shí)執(zhí)行泳赋,目的是為了得到可部署和可測(cè)試的軟件包,可以是每日定時(shí)進(jìn)行喇喉,也可以是一段時(shí)期祖今,如每個(gè)迭代集成一次,其構(gòu)建結(jié)果一般為一個(gè)可以獨(dú)立部署或運(yùn)行的軟件包拣技。
圖 4:集成構(gòu)建示意圖
2.5 藍(lán)綠發(fā)布
藍(lán)綠發(fā)布也稱熱部署千诬,是一種將用戶從一個(gè)版本幾乎瞬間轉(zhuǎn)移到另一個(gè)版本的方法,其關(guān)鍵在于將發(fā)布流程中的不同部分解耦膏斤。藍(lán)綠發(fā)布需要兩個(gè)相同的生產(chǎn)環(huán)境版本:藍(lán)環(huán)境徐绑、綠環(huán)境,在藍(lán)綠發(fā)布下莫辨,預(yù)發(fā)布環(huán)境和生產(chǎn)環(huán)境可以互為藍(lán)綠環(huán)境傲茄。
圖 5:藍(lán)綠發(fā)布示意圖
解決數(shù)據(jù)庫切換問題的方法:
是在切換之前暫時(shí)將應(yīng)用程序變成只讀狀態(tài)一段時(shí)間,恢復(fù)綠數(shù)據(jù)庫到藍(lán)數(shù)據(jù)庫沮榜,切換數(shù)據(jù)庫
讓應(yīng)用程序的新版本把數(shù)據(jù)庫事務(wù)同時(shí)在新舊兩個(gè)數(shù)據(jù)庫上執(zhí)行
對(duì)應(yīng)用程序進(jìn)行設(shè)計(jì)盘榨,讓數(shù)據(jù)庫遷移和升級(jí)流程獨(dú)立
2.6 灰度發(fā)布
灰度發(fā)布又叫金絲雀發(fā)布或A/B測(cè)試,是一種測(cè)試策略蟆融,提升試錯(cuò)能力较曼,減少新版本發(fā)布的風(fēng)險(xiǎn),灰度發(fā)布非常容易回滾
圖 6:灰度發(fā)布示意圖
將用戶按分類引致新版本和舊版本振愿,實(shí)現(xiàn)A/B測(cè)試
測(cè)試對(duì)象要具有代表性捷犹,需要業(yè)務(wù)人員參與,尤其是產(chǎn)品運(yùn)營團(tuán)隊(duì)
實(shí)現(xiàn)方式:
在應(yīng)用程序中增加特性開關(guān)
運(yùn)行時(shí)配置的改變
網(wǎng)絡(luò)規(guī)則的調(diào)整
逐漸增加負(fù)載冕末,檢查應(yīng)用程序的容量表現(xiàn)
重點(diǎn):任何共享資源要能在生產(chǎn)環(huán)境中的所有版本中相互兼容萍歉,如緩存、外部服務(wù)档桃、數(shù)據(jù)庫等
生產(chǎn)環(huán)境的多版本會(huì)導(dǎo)致管理的復(fù)雜度枪孩,應(yīng)盡量降低金絲雀的數(shù)目
2.7 服務(wù)可用性運(yùn)維優(yōu)化
圖 7:運(yùn)維優(yōu)化
服務(wù)降級(jí):在故障發(fā)生時(shí),關(guān)閉非核心業(yè)務(wù),保護(hù)核心業(yè)務(wù)
雙中心:雙中心同時(shí)提供服務(wù)蔑舞,IDC保持無狀態(tài)拒担,單機(jī)房故障時(shí),另一個(gè)機(jī)房平滑接管業(yè)務(wù)
統(tǒng)一調(diào)度:提供全網(wǎng)攻询、最優(yōu)从撼、實(shí)時(shí)、容錯(cuò)的用戶訪問調(diào)度
過載保護(hù):當(dāng)用戶請(qǐng)求超過服務(wù)能力時(shí)钧栖,服務(wù)的保護(hù)機(jī)制低零,避免雪崩
業(yè)務(wù)分離:根據(jù)服務(wù)的重要性等進(jìn)行服務(wù)解耦分離,實(shí)現(xiàn)服務(wù)的精細(xì)化管理拯杠,便于實(shí)現(xiàn)過載保護(hù)掏婶、服務(wù)降級(jí)等
立體化監(jiān)控:通過建立端到端的數(shù)據(jù)集成、分析潭陪、監(jiān)控體系雄妥,提供故障發(fā)現(xiàn)和定位能力
參考:王津銀的分享《我的互聯(lián)網(wǎng)運(yùn)維理論與實(shí)踐》
2.8 微服務(wù)
微服務(wù)是一種架構(gòu)方法,強(qiáng)調(diào)將應(yīng)用拆分成由跨職能團(tuán)隊(duì)管理的單目標(biāo)依溯、松散耦合的多個(gè)服務(wù)茎芭,以提高軟件系統(tǒng)交付效率和質(zhì)量。
微服務(wù)與編程語言誓沸、平臺(tái)、操作系統(tǒng)無關(guān)壹粟。它將龐大的應(yīng)用拆分成更小更簡單的應(yīng)用拜隧,這些龐大的應(yīng)用一般都是打成一個(gè)軟件包。每個(gè)應(yīng)用只需要做好一件事趁仙,微服務(wù)中的“微”就是指服務(wù)的功能范圍洪添,而不是指代碼行數(shù)(LOC)少。微服務(wù)不僅僅是一種新型的架構(gòu)模型雀费,也是一直新型的組織模型干奢,微服務(wù)在改變交付方式。
*微服務(wù)與DevOps相輔相成盏袄,微服務(wù)意味著更快的交付周期忿峻、更適合持續(xù)交付的應(yīng)用架構(gòu)、更完善的服務(wù)監(jiān)控辕羽、更完善的跨職能協(xié)作逛尚,這些都是DevOps的目標(biāo)。DevOps的成熟也可以促進(jìn)微服務(wù)的實(shí)現(xiàn)刁愿,更快的交付方式绰寞、更快的故障修復(fù)時(shí)間都會(huì)微服務(wù)的交付奠定了基礎(chǔ)。 *
微服務(wù)關(guān)鍵特點(diǎn)
領(lǐng)域驅(qū)動(dòng)設(shè)計(jì):采用Eric Evan的領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)可以很容易的實(shí)現(xiàn)功能的拆分
單一職責(zé)原則:每個(gè)服務(wù)只負(fù)責(zé)做好功能的一個(gè)完整部分即可
顯示地發(fā)布接口:生產(chǎn)者服務(wù)發(fā)布的接口一定有對(duì)應(yīng)的消費(fèi)者服務(wù)
獨(dú)立的DURS:即部署Deploy、更新Update滤钱、替換Replace觉壶、擴(kuò)容Scale,每個(gè)服務(wù)都可以獨(dú)立的部署件缸、更新铜靶、替換和擴(kuò)容
輕量級(jí)通信:服務(wù)之間的通信采用基于HTTP的REST、基于WebSocket的STOMP以及其他相似的輕量級(jí)協(xié)議
微服務(wù)的優(yōu)勢(shì)
獨(dú)立擴(kuò)容
獨(dú)立升級(jí)
易于維護(hù)
潛在的異質(zhì)和多語支持
錯(cuò)誤\資源隔離
改進(jìn)跨團(tuán)隊(duì)溝通
微服務(wù)的前提條件
服務(wù)復(fù)制
每個(gè)服務(wù)都應(yīng)該可復(fù)制停团,典型的方式是橫向克隆和縱向分區(qū)旷坦。應(yīng)該有標(biāo)準(zhǔn)的機(jī)制使得服務(wù)應(yīng)該可以輕易的基于元數(shù)據(jù)進(jìn)行擴(kuò)容。
服務(wù)發(fā)現(xiàn)
服務(wù)的真正地址需要在服務(wù)部署并且可以使用時(shí)才會(huì)確定佑稠。服務(wù)終端地址動(dòng)態(tài)特性可以使用服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)來解決秒梅。每個(gè)服務(wù)向代理進(jìn)行注冊(cè)并提供詳細(xì)的信息,包括最終地址舌胶。其他的消費(fèi)者服務(wù)查詢代理并找出服務(wù)的地址并調(diào)用它捆蜀。有很多方法可以注冊(cè)和查找服務(wù),比如ZooKeeper幔嫂、etcd辆它、consul、Kubernetes履恩、Netflix Eureka等
服務(wù)監(jiān)控
分布式系統(tǒng)中一個(gè)重要的部分就是服務(wù)監(jiān)控和日志管理锰茉。這樣可以在服務(wù)有問題時(shí)執(zhí)行預(yù)防措施,比如一個(gè)服務(wù)訪問了未授權(quán)的資源等切心。ELK技術(shù)楈可以收集不同服務(wù)中日志并且提供可視化展示。其他可以實(shí)現(xiàn)分布式日志管理的工具還有Syslog绽昏、Logentries和Loggly
容錯(cuò)性
無論如何進(jìn)行測(cè)試协屡,軟件錯(cuò)誤總會(huì)出現(xiàn)的。在基于多種微服務(wù)的分布式系統(tǒng)中容錯(cuò)性更加重要全谤。核心理念不是“如何避免錯(cuò)誤”而是“如何處理錯(cuò)誤”肤晓。微服務(wù)自動(dòng)的采取措施以避免對(duì)用戶體驗(yàn)造成影響非常重要。斷路器模式允許在軟件中構(gòu)建容錯(cuò)性认然。Netflix的Hystrix和Ribbon都是該模式很好的實(shí)現(xiàn)庫补憾。
DevOps
對(duì)基于微服務(wù)的應(yīng)用而言,持續(xù)集成和持續(xù)部署至關(guān)重要卷员。這些實(shí)踐可以更早識(shí)別錯(cuò)誤余蟹,可以減少在構(gòu)建不同的服務(wù)時(shí)不同團(tuán)隊(duì)之間的協(xié)作成本。
微服務(wù)與大型應(yīng)用架構(gòu)對(duì)比
以電商網(wǎng)站購物車的用戶子刮、訂單威酒、產(chǎn)品管理為需求背景窑睁,對(duì)比微服務(wù)與大型應(yīng)用的架構(gòu)區(qū)別,微服務(wù)的優(yōu)勢(shì)也可以從架構(gòu)圖對(duì)比中得到驗(yàn)證
微服務(wù)架構(gòu)設(shè)計(jì)模式
RedHat整理出6種微服務(wù)架構(gòu)設(shè)計(jì)模式葵孤,分別是聚合模式担钮、代理模式、鏈?zhǔn)侥J接热浴⒎种J襟锝颉⒐蚕砟J健⑾⒛J?/p>
常見的聚合模式和消息模式架構(gòu)圖如下:
聚合模式 將多個(gè)微服務(wù)聚合成一個(gè)組合服務(wù)
消息模式
采用消息系統(tǒng)異步的實(shí)現(xiàn)微服務(wù)之家的訪問
參考:開啟微服務(wù)之旅
2.9 12-FACTORS
12-FACTORS是Heroku平臺(tái)總結(jié)SaaS應(yīng)用開發(fā)經(jīng)驗(yàn)得出的宰啦,是開發(fā)SaaS應(yīng)用的實(shí)踐標(biāo)準(zhǔn)互纯,基于12-FACTORS構(gòu)建出的SaaS服務(wù)的特點(diǎn):
使用標(biāo)準(zhǔn)化流程自動(dòng)配置
獨(dú)立于操作系統(tǒng)正林,具有很強(qiáng)的可以移植性
適合部署在云計(jì)算平臺(tái)
將開發(fā)環(huán)境和生產(chǎn)環(huán)境的差異降至最低拐云,并使用持續(xù)交付實(shí)施敏捷開發(fā)
可以在工具查吊、架構(gòu)和開發(fā)流程不發(fā)生明顯變化的前提下實(shí)現(xiàn)擴(kuò)展
1. 代碼庫
一個(gè)代碼庫(Codebase),多份部署(deploy)
12-Factor應(yīng)用都應(yīng)該使用版本控制系統(tǒng)加以管理漓柑。代碼庫和應(yīng)用之間保持一一對(duì)應(yīng)的關(guān)系:
如果存在多個(gè)代碼庫教硫,就不能稱為一個(gè)應(yīng)用,而是一個(gè)分布式系統(tǒng)辆布。分布式系統(tǒng)中的每個(gè)組件都是一個(gè)獨(dú)立的應(yīng)用瞬矩,都可以獨(dú)立適用12-Factor原則。
多個(gè)應(yīng)用共享一個(gè)代碼庫有悖于12-Factor原則锋玲,可以將共用代碼拆分為獨(dú)立的類庫景用,以便進(jìn)行依賴管理
盡管每個(gè)應(yīng)用只對(duì)應(yīng)一個(gè)代碼庫,但可以同時(shí)存在多份部署惭蹂。每份部署相當(dāng)于運(yùn)行了一個(gè)應(yīng)用的實(shí)例伞插。通常會(huì)有一個(gè)生產(chǎn)環(huán)境,一個(gè)或多個(gè)預(yù)發(fā)布環(huán)境剿干,一個(gè)或多個(gè)測(cè)試環(huán)境。此外穆刻,每個(gè)開發(fā)人員都會(huì)在自己本地環(huán)境運(yùn)行一個(gè)應(yīng)用實(shí)例置尔,這些都相當(dāng)于一份部署。 所有部署的代碼庫相同氢伟,但每份部署可以使用其不同的版本榜轿。比如,開發(fā)人員可能有一些提交還沒有同步至預(yù)發(fā)布環(huán)境朵锣;預(yù)發(fā)布環(huán)境也有一些提交沒有同步至生產(chǎn)環(huán)境谬盐。但它們都共享一個(gè)代碼庫,我們就認(rèn)為它們只是相同應(yīng)用的不同部署而已诚些。
2. 依賴
顯式聲明依賴關(guān)系( dependency )
大多數(shù)編程語言都會(huì)提供一個(gè)打包系統(tǒng)飞傀,用來分發(fā)類庫皇型,如:Perl的CPAN或是Ruby的Rubygems。通過打包系統(tǒng)安裝的類庫可以是系統(tǒng)級(jí)的(稱之為 “site packages”)砸烦,或僅供某個(gè)應(yīng)用程序使用弃鸦,部署在相應(yīng)的目錄中(稱之為 “vendoring” 或 “bunding”)。
12-Factor規(guī)則下的應(yīng)用程序不會(huì)隱式依賴系統(tǒng)級(jí)的類庫幢痘。 它一定通過 依賴清單 唬格,確切地聲明所有依賴項(xiàng)。此外颜说,在運(yùn)行過程中通過 依賴隔離 工具來確保程序不會(huì)調(diào)用系統(tǒng)中存在但清單中未聲明的依賴項(xiàng)购岗。這一做法會(huì)統(tǒng)一應(yīng)用到生產(chǎn)和開發(fā)環(huán)境。
顯式聲明依賴的優(yōu)點(diǎn)之一是為新進(jìn)開發(fā)者簡化了環(huán)境配置流程门粪。新進(jìn)開發(fā)者可以檢出應(yīng)用程序的基準(zhǔn)代碼喊积,安裝編程語言環(huán)境和它對(duì)應(yīng)的依賴管理工具,只需通過一個(gè) 構(gòu)建命令 來安裝所有的依賴項(xiàng)庄拇,即可開始工作注服。
12-Factor 應(yīng)用同樣不會(huì)隱式依賴某些系統(tǒng)工具,如curl措近。即使這些工具存在于幾乎所有系統(tǒng)溶弟,但終究無法保證所有未來的系統(tǒng)都能支持應(yīng)用順利運(yùn)行,或是能夠和應(yīng)用兼容瞭郑。如果應(yīng)用必須使用到某些系統(tǒng)工具辜御,那么這些工具應(yīng)該被包含在應(yīng)用之中。
3. 配置
在環(huán)境中存儲(chǔ)配置
通常屈张,應(yīng)用的配置在不同部署(預(yù)發(fā)布擒权、生產(chǎn)環(huán)境、開發(fā)環(huán)境等等)間會(huì)有很大差異阁谆。這其中包括:
數(shù)據(jù)庫碳抄,Memcached,以及其他后端服務(wù)的配置
第三方服務(wù)的證書
每份部署特有的配置场绿,如域名等
有些應(yīng)用在代碼中使用常量保存配置剖效,這與12-Factor所要求的代碼和配置嚴(yán)格分離顯然背道而馳。配置文件在各部署間存在大幅差異焰盗,代碼卻完全一致璧尸。
判斷一個(gè)應(yīng)用是否正確地將配置排除在代碼之外,一個(gè)簡單的方法是看該應(yīng)用的基準(zhǔn)代碼是否可以立刻開源熬拒,而不用擔(dān)心會(huì)暴露任何敏感的信息爷光。
12-Factor推薦將應(yīng)用的配置存儲(chǔ)于 環(huán)境變量 中( env vars, env )。環(huán)境變量可以非常方便地在不同的部署間做修改澎粟,卻不動(dòng)一行代碼蛀序;與配置文件不同欢瞪,不小心把它們簽入代碼庫的概率微乎其微;與一些傳統(tǒng)的解決配置問題的機(jī)制(比如 Java 的屬性配置文件)相比哼拔,環(huán)境變量與語言和系統(tǒng)無關(guān)引有。
12-Factor 應(yīng)用中,環(huán)境變量的粒度要足夠小倦逐,且相對(duì)獨(dú)立譬正。它們永遠(yuǎn)也不會(huì)組合成一個(gè)所謂的“環(huán)境”,而是獨(dú)立存在于每個(gè)部署之中檬姥。當(dāng)應(yīng)用程序不斷擴(kuò)展曾我,需要更多種類的部署時(shí),這種配置管理方式能夠做到平滑過渡健民。
4. 后端服務(wù)
把后端服務(wù)(backing services)當(dāng)作附加資源
后端服務(wù)是指程序運(yùn)行所需要的通過網(wǎng)絡(luò)調(diào)用的各種服務(wù)抒巢,如數(shù)據(jù)庫(MySQL),消息/隊(duì)列系統(tǒng)(RabbitMQ)秉犹,SMTP郵件發(fā)送服務(wù)(Postfix)蛉谜,以及緩存系統(tǒng)(Memcached)。
12-Factor 應(yīng)用不會(huì)區(qū)別對(duì)待本地或第三方服務(wù)崇堵。 對(duì)應(yīng)用程序而言型诚,兩種都是附加資源,通過一個(gè)url或是其他存儲(chǔ)在配置中的服務(wù)定位/服務(wù)證書來獲取數(shù)據(jù)鸳劳。12-Factor應(yīng)用的任意部署狰贯,都應(yīng)該可以在不進(jìn)行任何代碼改動(dòng)的情況下,將本地MySQL數(shù)據(jù)庫換成第三方服務(wù)(例如Amazon RDS)赏廓。類似的涵紊,本地SMTP服務(wù)應(yīng)該也可以和第三方SMTP服務(wù)互換。上述2個(gè)例子中幔摸,僅需修改配置中的資源地址摸柄。
每個(gè)不同的后端服務(wù)是一份資源。例如既忆,一個(gè)MySQL數(shù)據(jù)庫是一個(gè)資源驱负,兩個(gè)MySQL數(shù)據(jù)庫(用來數(shù)據(jù)分區(qū))就被當(dāng)作是2個(gè)不同的資源。12-Factor應(yīng)用將這些數(shù)據(jù)庫都視作附加資源尿贫,這些資源和它們附屬的部署保持松耦合电媳。
部署可以按需加載或卸載資源踏揣。例如庆亡,如果應(yīng)用的數(shù)據(jù)庫服務(wù)由于硬件問題出現(xiàn)異常,管理員可以從最近的備份中恢復(fù)一個(gè)數(shù)據(jù)庫捞稿,卸載當(dāng)前的數(shù)據(jù)庫又谋,然后加載新的數(shù)據(jù)庫 – 整個(gè)過程都不需要修改代碼拼缝。
5. 構(gòu)建,發(fā)布彰亥,運(yùn)行
嚴(yán)格分離構(gòu)建和運(yùn)行
基準(zhǔn)代碼 轉(zhuǎn)化為一份部署(非開發(fā)環(huán)境)需要以下三個(gè)階段:
構(gòu)建階段 是指將代碼倉庫轉(zhuǎn)化為可執(zhí)行包的過程咧七。構(gòu)建時(shí)會(huì)使用指定版本的代碼,獲取和打包依賴項(xiàng)任斋,編譯成二進(jìn)制文件和資源文件继阻。
發(fā)布階段 會(huì)將構(gòu)建的結(jié)果和當(dāng)前部署所需 配置 相結(jié)合,并能夠立刻在運(yùn)行環(huán)境中投入使用废酷。
運(yùn)行階段 (或者說“運(yùn)行時(shí)”)是指針對(duì)選定的發(fā)布版本瘟檩,在執(zhí)行環(huán)境中啟動(dòng)一系列應(yīng)用程序 進(jìn)程。 代碼被構(gòu)建澈蟆,然后和配置結(jié)合成為發(fā)布版本
12-facfor 應(yīng)用嚴(yán)格區(qū)分構(gòu)建墨辛,發(fā)布,運(yùn)行這三個(gè)步驟趴俘。 舉例來說睹簇,直接修改處于運(yùn)行狀態(tài)的代碼是非常不可取的做法,因?yàn)檫@些修改很難再同步回構(gòu)建步驟寥闪。
部署工具通常都提供了發(fā)布管理工具太惠,最引人注目的功能是退回至較舊的發(fā)布版本。比如橙垢, CAPIstrano 將所有發(fā)布版本都存儲(chǔ)在一個(gè)叫 releases 的子目錄中垛叨,當(dāng)前的在線版本只需映射至對(duì)應(yīng)的目錄即可。該工具的 rollback 命令可以很容易地實(shí)現(xiàn)回退版本的功能柜某。
每一個(gè)發(fā)布版本必須對(duì)應(yīng)一個(gè)唯一的發(fā)布 ID嗽元,例如可以使用發(fā)布時(shí)的時(shí)間戳(2011-04-06-20:32:17),亦或是一個(gè)增長的數(shù)字(v100)喂击。發(fā)布的版本就像一本只能追加的賬本剂癌,一旦發(fā)布就不可修改,任何的變動(dòng)都應(yīng)該產(chǎn)生一個(gè)新的發(fā)布版本翰绊。
新的代碼在部署之前佩谷,需要開發(fā)人員觸發(fā)構(gòu)建操作。但是监嗜,運(yùn)行階段不一定需要人為觸發(fā)谐檀,而是可以自動(dòng)進(jìn)行。如服務(wù)器重啟裁奇,或是進(jìn)程管理器重啟了一個(gè)崩潰的進(jìn)程桐猬。因此,運(yùn)行階段應(yīng)該保持盡可能少的模塊刽肠,這樣假設(shè)半夜發(fā)生系統(tǒng)故障而開發(fā)人員又捉襟見肘也不會(huì)引起太大問題溃肪。構(gòu)建階段是可以相對(duì)復(fù)雜一些的免胃,因?yàn)殄e(cuò)誤信息能夠立刻展示在開發(fā)人員面前,從而得到妥善處理惫撰。
6. 進(jìn)程
以一個(gè)或多個(gè)無狀態(tài)進(jìn)程運(yùn)行應(yīng)用
7. 端口綁定
通過端口綁定(Port binding)來提供服務(wù)
8. 并發(fā)
通過進(jìn)程模型進(jìn)行擴(kuò)展
9. 易處理
快速啟動(dòng)和優(yōu)雅終止可最大化健壯性
10. 開發(fā)環(huán)境與線上環(huán)境等價(jià)
盡可能的保持開發(fā)羔沙,預(yù)發(fā)布,線上環(huán)境相同
從以往經(jīng)驗(yàn)來看厨钻,開發(fā)環(huán)境(即開發(fā)人員的本地 部署)和線上環(huán)境(外部用戶訪問的真實(shí)部署)之間存在著很多差異扼雏。這些差異表現(xiàn)在以下三個(gè)方面:
時(shí)間差異: 開發(fā)人員正在編寫的代碼可能需要幾天,幾周夯膀,甚至幾個(gè)月才會(huì)上線呢蛤。
人員差異: 開發(fā)人員編寫代碼,運(yùn)維人員部署代碼棍郎。
工具差異: 開發(fā)人員或許使用 Nginx其障,SQLite,OS X涂佃,而線上環(huán)境使用 Apache励翼,MySQL 以及 Linux。
12-Factor 應(yīng)用想要做到 持續(xù)部署 就必須縮小本地與線上差異辜荠。 再回頭看上面所描述的三個(gè)差異:
縮小時(shí)間差異:開發(fā)人員可以幾小時(shí)汽抚,甚至幾分鐘就部署代碼。
縮小人員差異:開發(fā)人員不只要編寫代碼伯病,更應(yīng)該密切參與部署過程以及代碼在線上的表現(xiàn)造烁。
縮小工具差異:盡量保證開發(fā)環(huán)境以及線上環(huán)境的一致性。
將上述總結(jié)變?yōu)橐粋€(gè)表格如下:
[td]
傳統(tǒng)應(yīng)用12-Factor 應(yīng)用
每次部署間隔數(shù)周幾小時(shí)
開發(fā)人員 vs 運(yùn)維人員不同的人相同的人
開發(fā)環(huán)境 vs 線上環(huán)境不同盡量接近
后端服務(wù) 是保持開發(fā)與線上等價(jià)的重要部分午笛,例如數(shù)據(jù)庫惭蟋,隊(duì)列系統(tǒng),以及緩存药磺。許多語言都提供了簡化獲取后端服務(wù)的類庫告组,例如不同類型服務(wù)的 適配器 。下列表格提供了一些例子癌佩。
[td]
類型語言類庫適配器
數(shù)據(jù)庫Ruby/RailsActiveRecordMySQL, PostgreSQL, SQLite
隊(duì)列Python/DjangoCeleryRabbitMQ, Beanstalkd, Redis
緩存Ruby/RailsActiveSupport::CacheMemory, filesystem, Memcached
開發(fā)人員有時(shí)會(huì)覺得在本地環(huán)境中使用輕量的后端服務(wù)具有很強(qiáng)的吸引力木缝,而那些更重量級(jí)的健壯的后端服務(wù)應(yīng)該使用在生產(chǎn)環(huán)境。例如围辙,本地使用 SQLite 線上使用 PostgreSQL我碟;又如本地緩存在進(jìn)程內(nèi)存中而線上存入 Memcached。
12-Factor 應(yīng)用的開發(fā)人員應(yīng)該反對(duì)在不同環(huán)境間使用不同的后端服務(wù)?姚建,即使適配器已經(jīng)可以幾乎消除使用上的差異矫俺。這是因?yàn)椋煌暮蠖朔?wù)意味著會(huì)突然出現(xiàn)的不兼容,從而導(dǎo)致測(cè)試恳守、預(yù)發(fā)布都正常的代碼在線上出現(xiàn)問題。這些錯(cuò)誤會(huì)給持續(xù)部署帶來阻力贩虾。從應(yīng)用程序的生命周期來看催烘,消除這種阻力需要花費(fèi)很大的代價(jià)。
與此同時(shí)缎罢,輕量的本地服務(wù)也不像以前那樣引人注目伊群。借助于Homebrew,apt-get等現(xiàn)代的打包系統(tǒng)策精,諸如Memcached舰始、PostgreSQL、RabbitMQ 等后端服務(wù)的安裝與運(yùn)行也并不復(fù)雜咽袜。此外丸卷,使用類似Chef和Puppet的聲明式配置工具,結(jié)合像Vagrant這樣輕量的虛擬環(huán)境就可以使得開發(fā)人員的本地環(huán)境與線上環(huán)境無限接近询刹。與同步環(huán)境和持續(xù)部署所帶來的益處相比谜嫉,安裝這些系統(tǒng)顯然是值得的。
不同后端服務(wù)的適配器仍然是有用的凹联,因?yàn)樗鼈兛梢允挂浦埠蠖朔?wù)變得簡單沐兰。但應(yīng)用的所有部署,這其中包括開發(fā)蔽挠、預(yù)發(fā)布以及線上環(huán)境住闯,都應(yīng)該使用同一個(gè)后端服務(wù)的相同版本。
11. 日志
把日志當(dāng)作事件流
12. 管理進(jìn)程
后臺(tái)管理任務(wù)當(dāng)作一次性進(jìn)程運(yùn)行
注:12-Factor應(yīng)用:按照12-FACTORS要求來設(shè)計(jì)的應(yīng)用 原文參考:http://12factor.net/