從開發者的角度看:打包和部署

b2f5 9年前發布 | 34K 次閱讀 打包

如今的互聯網軟件越來越碎片化(micro services),Queue無處不在,服務依賴越來越多,使得軟件功能的開發,到軟件功能的部署,中間有很長的一段路。這段路,是持續集成(Continuous Integration)和持續發布(Continous Delivery)的基石,一般由devOps包圓了,對從不涉身其中的dev而言,看上去就像ops們用了黑魔法,設了道傳送門一樣,讓寫好的代碼 biu的一下就變成了運行在瀏覽器,或者手機上的鮮活頁面。本著不懂點devOps的dev不是好pm的態度,本文簡單講講軟件發布過程中的兩個黑魔法:打包(packaging)和部署(deploying)。

我們先看「打包」。

打包


打包字面上的理解是把你的應用和其依賴的組件組織在一起,以便于分發到目標系統上。客戶端軟件的時代,如office 97燒錄成一個iso(便于刻在光盤上)就是個典型的打包的過程;互聯網時代,一個java項目生成 jar,python項目生成 wheel/egg,也是打包的過程。

打包的意義在于制作可以重復使用的軟件。所有瑣碎的活兒都在打包的時候完成了,而在要部署的目標系統上,無需使用源代碼,無需處理依賴,無需編譯,只要把打包好的軟件「安裝」好即可。我們知道,在計算機領域,合格的程序員傾向于消除一切重復的工作。打包的過程,實際上是一系列手工操作的合集,因此必然有相應的工具來幫助提高打包的效率。

打包軟件的元老級人物應該是 make。這個常常伴隨C/C++項目的任務管理工具的一大主要用途就是打包。當然,make 接近于 *nix shell 的語法并非人見人愛,于是各個語言都提供語言本身的任務管理工具,如grunt,rake。

簡單的應用,打包的過程可以很快,因為只需應用本身的編譯和依賴處理,秒級就可以完成;但復雜的應用可能需要數個鐘頭。比如說,一個嵌入式軟件需要用 buildroot 把 OS,dependencies 及應用軟件深度整合在一個可以直接燒錄在硬件的 firmware 里,其 full build 可能需要幾個小時。另外一個例子是一個復雜的系統可能會使用 ansible/puppet/chef 這樣的工具將多個代碼庫的不同部分裝進不同的 aws ec2 instances 中,安裝依賴,配置系統時鐘,配置 nginx,supervisor 等等服務,然后把這些 instances 制作成一個個 AMI(Amazon Machine Images),供日后部署之用。這往往也需要耗費半個小時到幾個小時的時間。

打包的過程中,包括之后部署的過程中,還需要一樣東西:資源管理工具。因為,就像 micro service 需要 consul 這樣的工具提供服務發現,docker 需要 docker registry 提供 repository 一樣,打包好的軟件需要一個合適的地方放置,便于版本管理,部署以及可能的回退。

這個工具可以是S3,可以是自行開發的 repository,也可以用開源的 archiva 或 artifactory。后兩者做java的同學應該有所耳聞。這樣的資源管理工具有什么用?以python為例,如果你的軟件會打包出很多私有的 egg/wheel 包,這些包無法被公開放置在 pypi 上,那么你可以用 artifactory(或achiva)取代 pypi,成為你 pip install 的 index server。artifactory 上沒有的包(公共包)會自動去 pypi 上取。同樣的,debian 的 index server,docker 的 registry 都可以用這樣的工具構建。

部署


不少人把「打包」和「部署」兩件事混在一起,是因為二者經常在一起執行:打包之后,不待喘息,就立刻部署。但部署的動作其實是獨立的,一份打包好的軟件,按使用場景,可能會有多種部署。互聯網軟件的部署,往往是相當復雜的,光線上環境而言,就有開發環境,測試環境,以及生產環境。這還不算生產環境中可能存在的各種版本(提供外部API的同學應該心有戚戚焉),所以,部署往往是比打包更讓人頭疼的事情。

我們舉個具體的例子:一個線上的日程系統,運行在 aws 里,主要使用 dynamodb,elasticache,ec2 和 s3。開發環境無需考慮 scaling,以單臺服務器承載所有服務,沒有 ELB / auto-scaling,數據是線上數據的子集;測試環境有 ELB,服務分布在不同的EC2上,每種服務都有兩臺服務器做HA,但沒有 auto-scaling;線上服務則有 ELB / auto-scaling。

一個新功能的開發和集成的過程中,開發環境可能會被部署多次;當集成完成后,系統會被部署到生產測試環境;而測試結束后,系統可以以藍綠發布(blue green deployment)的方式部署到生產環境;或者,選取一定樣本的用戶做灰度發布(gated launch 或者 A/B test)。

在aws的世界里,部署的主要工具是 cloudformation / elastic beanstalk,因為在打包的過程中,已經通過 ansible/puppet/chef/docker 等生成好了 AMI 或者 docker image;在非aws的世界里,ansible等工具也被用于部署。

如之前例子所示,部署主要是做資源的調配。開發環境毋須消耗太多資源,所以分配少一些;生產環境是現金奶牛,必須保證資源的全力供應。

當然,部署并不單單是資源的調配,它還是服務的 ochestration(嗯,這詞比較高大上)。拿 logging 為例,如何把分散在各個服務器上的日志集中起來用于查詢和分析,就是部署的一項任務。

藍綠發布的思想其實比較簡單,就是提供兩套一樣的生產環境(production / staging),通過DNS對流量進行切換。如下圖:

(圖片來自:BlueGreenDeployment

當 staging 足夠穩定時,可以通過DNS切換,把流量從 production 轉入 staging。待穩定后,staging 變為 production,原有的 production 轉為 staging,可以被 shutdown,也可以被用于下一個 release。如果使用AWS,可以通過 route53 進行 DNS redirection,或者 ELB 的 auto-scaling group進行藍綠發布。

藍綠發布的好處是一旦發現問題,可以迅速回滾。

灰度發布在王淮的《打造非死book》一書中有介紹:基本思想就是發布的時候控制發布的人群及其比例。比如先1%的用戶,再擴大到5%,直至100%。人群可以根據多種屬性來篩選,如:年齡、性別、國家、城市、語言、學歷、工作單位等。

灰度發布的缺點是如果系統有不可逆的更改,則不能使用;對藍綠發布而言,可以使用,但是系統不能回滾。

關于打包和發布的基礎知識,就講這么些。真正操作起來還是挺復雜的。就拿部署的速度而言,就有很多學問:層層緩存,最小化任務集合,對 full build 和 incremental build 采取不同的優化方式等。有同學可能會有疑問:如果打包和部署都已經自動化了,速度快一點,慢一點又有什么影響?殊不知以互聯網的速度,如果你做一次部署要兩小時,人家只需要五分鐘,那么一天八小時內,你能部署四次,人家最多可以部署九十六次。效率提升差出來一到兩個量級后,對開發人員的效率而言,會產生質的變化。

來自:http://zhuanlan.zhihu.com/prattle/20062049

 本文由用戶 b2f5 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!