引子
云服務(wù)的熱度越來越高,IaaS、PaaS、SaaS開始逐漸為大家所知,論壇時(shí)期的那些草根站長也開始不自己購買服務(wù)器轉(zhuǎn)而使用云主機(jī)了,大環(huán)境在慢慢變好,特別是對創(chuàng)業(yè)人員來說。
不過所謂的云服務(wù)三個(gè)層次發(fā)展并不均衡,IaaS是真正做起來了,特別是aws,早就是一個(gè)很重要的收入源了,國內(nèi)來講,比較有名的就是阿里云、 UCloud、青云了,應(yīng)該也開始盈利了,可喜可賀。但是PaaS并沒有做起來,GAE、SAE、BAE、JAE應(yīng)該沒有一個(gè)稱得上成功。至于SaaS,在筆者的認(rèn)知里,無非就是提供給大眾用的一個(gè)網(wǎng)站,有賬號體系,不同賬號有自己的數(shù)據(jù),不做評價(jià)。
本文主要是想聊一下在當(dāng)前大環(huán)境下,我們應(yīng)該如何做開發(fā),行業(yè)應(yīng)該如何發(fā)展。哇,話題好大,口氣不小,每個(gè)人都有自己的理解,仁者見仁智者見智,筆者也只是碎碎念,可能觀點(diǎn)一無是處,錯(cuò)得離譜,讀者一笑置之,不要扔磚頭,砸到花花草草也是不好~
IaaS服務(wù)概述
首先,我們回顧一下現(xiàn)在IaaS廠商提供了什么
*云主機(jī)
這是必須的,否則就不是IaaS廠商了,至于用的Xen還是KVM,那咱們不關(guān)心,總之對用戶來講,拿到手的是一個(gè)指定CPU核數(shù)、指定內(nèi)存大小、指定磁盤大小和類型、指定網(wǎng)絡(luò)帶寬的機(jī)器。
如此一來,開發(fā)者無需去花費(fèi)幾千甚至幾萬塊購買物理服務(wù)器了,初期買個(gè)配置低的云主機(jī)還是比較省錢,而且不用關(guān)心操作系統(tǒng)、yum源、機(jī)架、網(wǎng)絡(luò)、交換機(jī)、網(wǎng)線、機(jī)房租賃費(fèi)用等等問題,著實(shí)省心不少。
*周邊服務(wù)
一個(gè)服務(wù)要想跑起來,光有服務(wù)器和操作系統(tǒng)是不夠的,我們通常還要依賴一些周邊服務(wù),比如數(shù)據(jù)庫、Cache、Redis、MQ、存儲、LB等等,如果只有云主機(jī),那我們需要自己在云主機(jī)上搭建并維護(hù)這些服務(wù)。對于一些資深棧溢出工程師那肯定是沒問題的,但是大部分人都是各有所長,一個(gè)好的開發(fā)并不一定是個(gè)好的DBA。
這些IaaS廠商也意識到這個(gè)問題,他們會把這些周邊服務(wù)統(tǒng)一管理、運(yùn)維,然后賣給開發(fā)者,其實(shí)這是個(gè)好事,IaaS廠商雇用專業(yè)的人士來打磨這些服務(wù),通常都要比我們在云主機(jī)上手工搭建的要穩(wěn)定、高效、安全、可用。而IaaS廠商統(tǒng)一處理這些周邊服務(wù)之后很容易形成規(guī)模效應(yīng),成本可以做得更低,穩(wěn)定性也更好,雙贏。
通常的IaaS廠商就是提供這些服務(wù)了,當(dāng)然,像AWS走在行業(yè)前面的巨頭,會提供更多其他的服務(wù),我們姑且不談。
IaaS下的開發(fā)
上節(jié)咱們簡單介紹了IaaS提供的服務(wù)、產(chǎn)品,那么在這樣的環(huán)境下,開發(fā)人員是怎么利用IaaS快速實(shí)現(xiàn)他們的產(chǎn)品原型的呢?
通常一個(gè)典型的產(chǎn)品可能包含三個(gè)與用戶交互的部分:web端、iOS手機(jī)端、Android手機(jī)端。而后端通常是有一個(gè)nginx前端,有業(yè)務(wù)邏輯部分,比如tomcat中跑的Java code、php-fpm驅(qū)動的php code、gunicorn驅(qū)動的Python code,會用到數(shù)據(jù)庫來做持久化,用到Cache來提高查詢速度,如果后端有些比較重量級的計(jì)算任務(wù)可能還會有個(gè)rpc服務(wù)。
哪部分需要自己搞,哪部分需要IaaS廠商來搞?
業(yè)務(wù)邏輯相關(guān)的代碼肯定是dev來開發(fā)的
nginx前面通常需要有個(gè)四層的負(fù)載均衡,也就是大家熟知的ELB了,這個(gè)是IaaS廠商提供
nginx、php語言環(huán)境、php-fpm(以PHP程序舉例)肯定是sre來搭建并運(yùn)維了,當(dāng)然,如果這個(gè)小公司只有一個(gè)技術(shù)人員,說不得就要通吃dev、qa、sre、fe、ui、ue的所有工作了
數(shù)據(jù)庫、Cache應(yīng)該由IaaS廠商提供,他們負(fù)責(zé)維護(hù)、備份、擴(kuò)容,只要提供給用戶一個(gè)連接地址即可
嗯,看起來IaaS廠商還是幫了我們一些忙的,一些系統(tǒng)、網(wǎng)絡(luò)、DBA運(yùn)維相關(guān)的事情用戶是不用操心的。
接下來這個(gè)創(chuàng)業(yè)公司的唯一的技術(shù)人員開始著手碼代碼了。雖然IaaS廠商已經(jīng)幫忙解決一部分問題了,接下來這個(gè)哥們還會遇到哪些問題呢?腦洞打開……
IaaS之后,缺失的云服務(wù)
說缺失可能并不準(zhǔn)確,因?yàn)橛行┓?wù)已經(jīng)有些公司在做了,只是目前并沒有與IaaS很好的結(jié)合起來
Code托管
代碼放在哪里?這是個(gè)問題。使用Github?不太好,因?yàn)檫@是個(gè)創(chuàng)業(yè)項(xiàng)目,原因如下:
Github是個(gè)用代碼交流的開發(fā)者社區(qū),開源代碼很適合放在上面,但這不代表私有項(xiàng)目也適合放在上面,而且Github私有repo是收費(fèi)的,雖然不貴,創(chuàng)業(yè)嘛,能省則省,特別是有替代服務(wù)的情況下
Github在國外,網(wǎng)絡(luò)狀況不是很好,經(jīng)常要連vpn才能使用,麻煩
Github不方便與內(nèi)部其他平臺(比如編譯平臺)整合,其實(shí)這個(gè)歸根結(jié)底還是網(wǎng)絡(luò)惹的禍,萬惡的那個(gè)啥啊
所以,國內(nèi)出了個(gè)gitcafe、出了個(gè)git.oschina.net、出了個(gè)coding.net,稍大一些的公司直接就自己搭建svn服務(wù)器或者gitlab服務(wù)器
這是一塊蛋糕,親愛的讀者,如果你是做IaaS的,可以嘗試與這些代碼托管服務(wù)商合作一下,畢竟,代碼是一切的開始。
Build平臺
編譯平臺、產(chǎn)品庫,這些名詞對于devops來說再熟悉不過了。這一節(jié)我們就來聊聊這部分話題:
代碼已經(jīng)托管起來了,那下一步是什么呢?編譯打包!沒錯(cuò),如果你使用的解釋型語言,比如PHP、Ruby體會可能不深,但如果是編譯型的,比如Java、Go、C++,估計(jì)就深有感觸了。code寫好了,要去測試、上線,首先要做的是編譯并打包。
最終的期望是:打成的包自包含Runtime,部署到線上任何一臺機(jī)器上都能跑起來,當(dāng)然了,前提是這些機(jī)器都是相同的操作系統(tǒng),相同的字長。為啥說要自包含呢?因?yàn)榫€上機(jī)器環(huán)境千差萬別,操作系統(tǒng)版本可能不同、Python版本可能不同、可能連wget命令都沒有,千萬不能依賴線上環(huán)境。
做這個(gè)平臺的關(guān)鍵是指定合理的規(guī)范
最終的發(fā)布包要是什么格式,包內(nèi)的文件是怎么個(gè)組織方式,meta信息應(yīng)該放在哪里,啟動腳本應(yīng)該放在哪里,打好的發(fā)布包放在哪里,應(yīng)該是一個(gè)整包還是散文件,平臺去哪里拉取用戶的打包產(chǎn)物……發(fā)布包最終是拿來部署的,故而規(guī)范的制定要考慮與部署系統(tǒng)的結(jié)合。
Runtime要提前準(zhǔn)備好以提高編配速度
我們剛才說最終的期望是打好的包要做到自包含Runtime,所以Java的項(xiàng)目需要包含JDK、Tomcat(或者Resin、Jetty之類的),Python的項(xiàng)目要包含Python的語言環(huán)境,還要準(zhǔn)備好Nginx之類的,這些常用軟件不能在編譯的時(shí)候去外網(wǎng)下載,應(yīng)該提前放到內(nèi)網(wǎng)或者編譯機(jī)上。
Docker Image &Docker Registry
Docker最近比較火,我們可以把 Docker Image看做是一種發(fā)布包,Docker Registry看做是一種產(chǎn)品庫。因?yàn)镈ocker Image就是一個(gè)自包含的可以在任何部署了Docker的機(jī)器上跑起來。而Dockerfile可以看作是一種打包規(guī)范,類似Heroku和 CloudFoundry中的buildpack
這一塊IaaS廠商并沒有提供,筆者覺得這也是一個(gè)可以做的方向,不知道有沒有創(chuàng)業(yè)公司已經(jīng)看到商機(jī)在這塊發(fā)力了。
Deploy工具
我們說Code已經(jīng)托管好了,又有編譯平臺負(fù)責(zé)打好包了,接下來就是部署了。作為CI的最后一公里,Deploy工具起到了很重要的作用,往QA環(huán)境部署、往沙盒環(huán)境部署、往小流量環(huán)境部署、線上全量部署都要用到。
說到底,部署就是一個(gè)按照某種并發(fā)策略去一批機(jī)器上批量執(zhí)行部署腳本的過程
嗯,筆者自認(rèn)為這句話總結(jié)得還算精辟,哈哈,只是不知道有多少人會贊同~
對于單個(gè)項(xiàng)目只有幾十臺機(jī)器而言,有針對性得寫一個(gè)部署腳本,批量ssh到對應(yīng)機(jī)器上跑一下完成部署是沒有問題的。但是這不夠規(guī)范,個(gè)人搞個(gè)人的,也難以形成業(yè)內(nèi)標(biāo)準(zhǔn),推進(jìn)軟件開發(fā)的步伐,對于幾百臺機(jī)器的大項(xiàng)目,ssh就很難完成了,批量建立信任關(guān)系也是一個(gè)比較麻煩的事情。
這個(gè)時(shí)候一個(gè)強(qiáng)悍的Deploy工具就派上用場了,這個(gè)工具要:
具備批量去各個(gè)機(jī)器執(zhí)行腳本的能力,而且要保證每個(gè)腳本不能多執(zhí)行了,不能少執(zhí)行了,每個(gè)機(jī)器上可能要部署一個(gè)agent來支持
并發(fā)策略要可調(diào)控,比如一個(gè)一個(gè)來做?還是每次做2個(gè)?5個(gè)?因?yàn)椴煌姆?wù)可承受的同時(shí)重啟的實(shí)例數(shù)目不一樣,所以這個(gè)并發(fā)策略要可配置
有既定規(guī)范流程,這個(gè)流程是指在單機(jī)執(zhí)行的一些步驟,先干什么,再干什么,最后干什么等等,我們要去分析抽象出一個(gè)通用流程,能夠滿足大部分項(xiàng)目部署需求
單機(jī)部署流程可定制,雖然我們已經(jīng)抽象了一個(gè)比較好的通用流程,但是總有一些特例是沒法用默認(rèn)方式滿足的,故而這個(gè)流程要可定制,插入用戶自己的特殊邏輯
最后達(dá)到的效果就是:用戶要發(fā)起部署,只要簡單的指定一些meta信息即可完成。meta信息可能包括:發(fā)布包地址、機(jī)器列表、進(jìn)程啟動賬號、部署目錄等等
aws有提供一個(gè)叫Deploy的服務(wù),不知道是否就是干這個(gè)事情的。
Config Center
我們在做Build平臺和Deploy工具的時(shí)候,必然要處理配置問題,因?yàn)椴煌捻?xiàng)目配置是不一樣的,甚至同一個(gè)項(xiàng)目,部署在不同的機(jī)器上配置都是不同的。但是對于一個(gè)項(xiàng)目而言,我們期望一次release動作用到的發(fā)布包都是相同的,不會因?yàn)榕渲貌煌龀啥鄠€(gè)發(fā)布包。這個(gè)不知道大家有沒有感觸,測試環(huán)境、沙盒環(huán)境、線上環(huán)境通常有自己的配置,所以有些人就為測試環(huán)境打一個(gè)包、為沙盒環(huán)境打一個(gè)包、為線上環(huán)境打一個(gè)包。這種做法在筆者看來是很不好的。因?yàn)镼A測試的那個(gè)包竟然不是線上用的包!那如何保證不出問題?!
我們推薦做成一個(gè)包,那就要屏蔽差異,把不同的配置信息抽出來。外部搭建一個(gè)Config Center就是一個(gè)方案。
配置信息通常不大,好多人可能很容易想到用Zookeeper實(shí)現(xiàn)一個(gè)。不過這篇文章中我們不談具體實(shí)現(xiàn),淘寶有個(gè)開源項(xiàng)目叫Diamond也是做類似事情的,大家如果有興趣可以參考一下,如果沒記錯(cuò)的話,Google的Borg系統(tǒng)中也是有一個(gè)配置中心的。
云主機(jī)and服務(wù)監(jiān)控
上面提到的幾點(diǎn)主要是針對code和deploy的,接下來咱們聊一下監(jiān)控。提到監(jiān)控這個(gè)詞,你想到了對什么的監(jiān)控?cpu、內(nèi)存、io、網(wǎng)絡(luò)、磁盤,嗯,沒錯(cuò),機(jī)器基礎(chǔ)監(jiān)控必須要有;進(jìn)程存活監(jiān)控、端口監(jiān)控、域名監(jiān)控,嗯,針對服務(wù)存活性的監(jiān)控,也必須要有。通常提供云監(jiān)控的IaaS廠商都會提供以上兩類監(jiān)控,夠了么?還有其他需求么?
你是否想過http 500次數(shù)的監(jiān)控?url響應(yīng)時(shí)間過長的監(jiān)控?api調(diào)用次數(shù)過多的監(jiān)控?log中Error字樣或Exception字樣過多的監(jiān)控?嗯,這些就屬于是一些業(yè)務(wù)自定義監(jiān)控了。能提供這種監(jiān)控的IaaS就不多見了。而實(shí)際上,這是很有需求的,就像我剛才舉的這幾個(gè)例子,你是dev的話你肯定也想知道吧?
但是這些監(jiān)控每個(gè)服務(wù)都不一樣,作為IaaS平臺方,應(yīng)該從哪里拉取這些監(jiān)控?cái)?shù)據(jù)呢?顯然,沒地方!應(yīng)該讓app方告訴平臺方pull的接口是什么,或者平臺方直接提供一個(gè)push接口,讓app自己去收集數(shù)據(jù)然后push。不管是哪種方式,平臺方都要制定數(shù)據(jù)格式規(guī)范,比如什么樣的接口才可以被拉取,拉取到的數(shù)據(jù)應(yīng)該是什么格式,或者什么樣的數(shù)據(jù)才能push,push的方式是什么樣的,諸如此類。
如此一來,我們開發(fā)產(chǎn)品的這些苦逼碼農(nóng)不但可以了解到我們使用的云主機(jī)的運(yùn)行情況,服務(wù)的存活情況,也可以了解到服務(wù)的性能情況,穩(wěn)定情況,是不是不錯(cuò)?
LB接口化
IaaS廠商剛剛起步的時(shí)候,第一個(gè)要做的顯然是云主機(jī);云主機(jī)搞定之后呢?顯然是RDS;RDS搞定之后呢?大部分廠商都會選擇去做LB,因?yàn)橛蛎竺嬷苯优渲闷邔觭erver還是有很大的問題,那就是七層server宕機(jī)之后無法及時(shí)從域名中摘掉,因?yàn)閐ns是有比較久的生效時(shí)間的嘛~于是 LVS之類的四層負(fù)載均衡設(shè)備就派上用場了,也就是aws中所謂的ELB。
通常IaaS廠商都會提供LB,但是并不是所有廠商都提供api讓用戶去修改vip對應(yīng)的rs,而這點(diǎn)在筆者看來是一個(gè)非常重要的功能,最好盡快提供。它有什么用呢?LB已經(jīng)可以自動摘掉宕機(jī)的七層實(shí)例了,還不夠?這個(gè)api主要是用于做自動遷移的,即:新擴(kuò)容的rs可以及時(shí)加進(jìn)來,宕機(jī)的rs可以及時(shí)摘掉。這個(gè)加進(jìn)來和摘掉的動作要自動化!故而LB要接口化。
All in Automation
之前我們已經(jīng)提到需要一個(gè)Deploy工具,讓用戶方便得部署他們的服務(wù),快速迭代,持續(xù)集成。但是在部署的過程中用戶仍然要指定很多信息,比如要部署的機(jī)器列表,run應(yīng)用的Linux賬號,部署完成之后還要手工修改ELB的配置,修改vip對應(yīng)的rs(別怕,通常是不用修改的,只有個(gè)別情況比如擴(kuò)容的時(shí)候才需要)。整個(gè)過程比較復(fù)雜。特別是分配機(jī)器列表,如果模塊比較多,我們?yōu)榱烁玫馁Y源利用通常會選擇混部,比如io密集型的與cpu密集型的部署到一臺機(jī)器上,這樣一來我們要花心思去分配,能不能讓平臺自動化去調(diào)度完成?
比較好的用戶使用方式可能是這樣的:
用戶提供發(fā)布包,提供所有可用的機(jī)器列表,告訴平臺要部署的服務(wù)是io密集型的還是cpu密集型的,告訴平臺這個(gè)服務(wù)要注冊的ELB vip是什么以及這個(gè)服務(wù)的服務(wù)端口是什么,然后平臺自動去調(diào)度部署。
平臺可能的做法:
通過監(jiān)控系統(tǒng)收集到該用戶各個(gè)云主機(jī)的資源利用情況,按照比較好的混部策略,找到比較適合部署這個(gè)服務(wù)的云主機(jī),部署少量幾個(gè)app實(shí)例,把這幾個(gè)實(shí)例注冊到對應(yīng)的vip上去(LB接口化很重要吧,嘿)提供服務(wù),然后監(jiān)控這些實(shí)例是否掛掉,如果掛掉了自動拉起,如果實(shí)例所在的機(jī)器都掛了,自動將實(shí)例遷移到其他好的云主機(jī)上去,同時(shí)修改vip對應(yīng)的rs配置,然后監(jiān)控這個(gè)vip的流量,如果流量太高,自動擴(kuò)容,找新的云主機(jī)部署新實(shí)例,將新的rs加到該vip下。
目前先想到這么多,這是筆者腦袋中的一個(gè)不甚成熟的藍(lán)圖,諸位看官有補(bǔ)充的歡迎留言。如果看完之后碰撞出了你腦袋中的思維火花,可以選擇打賞我包煙錢,我不會介意的,嗯?不知道我的支付寶?哦,就是我的手機(jī)號,嗯?不知道我的手機(jī)號?打電話問嘛……