引子
云服務的熱度越來越高宝踪,IaaS加勤、PaaS联四、SaaS開始逐漸為大家所知境蜕,論壇時期的那些草根站長也開始不自己購買服務器轉而使用云主機了,大環(huán)境在慢慢變好汽馋,特別是對創(chuàng)業(yè)人員來說侮东。
不過所謂的云服務三個層次發(fā)展并不均衡,IaaS是真正做起來了豹芯,特別是aws悄雅,早就是一個很重要的收入源了,國內來講铁蹈,比較有名的就是阿里云宽闲、UCloud、青云了,應該也開始盈利了容诬,可喜可賀娩梨。但是PaaS并沒有做起來,GAE览徒、SAE狈定、BAE、JAE應該沒有一個稱得上成功吱殉。至于SaaS掸冤,在筆者的認知里,無非就是提供給大眾用的一個網站友雳,有賬號體系稿湿,不同賬號有自己的數據,不做評價押赊。
本文的標題是《IaaS之后》饺藤,主要是想聊一下在當前大環(huán)境下,我們應該如何做開發(fā)流礁,行業(yè)應該如何發(fā)展涕俗。哇,話題好大神帅,口氣不小再姑,每個人都有自己的理解,仁者見仁智者見智找御,筆者也只是碎碎念元镀,可能觀點一無是處,錯得離譜霎桅,讀者一笑置之栖疑,不要扔磚頭,砸到花花草草也是不好~
IaaS服務概述
首先滔驶,我們回顧一下現在IaaS廠商提供了什么
*云主機
這是必須的遇革,否則就不是IaaS廠商了,至于用的Xen還是KVM揭糕,那咱們不關心萝快,總之對用戶來講,拿到手的是一個指定CPU核數著角、指定內存大小杠巡、指定磁盤大小和類型、指定網絡帶寬的機器雇寇。
如此一來,開發(fā)者無需去花費幾千甚至幾萬塊購買物理服務器了,初期買個配置低的云主機還是比較省錢锨侯,而且不用關心操作系統(tǒng)嫩海、yum源、機架囚痴、網絡叁怪、交換機、網線深滚、機房租賃費用等等問題奕谭,著實省心不少。
*周邊服務
一個服務要想跑起來痴荐,光有服務器和操作系統(tǒng)是不夠的血柳,我們通常還要依賴一些周邊服務,比如數據庫生兆、Cache难捌、Redis、MQ鸦难、存儲根吁、LB等等,如果只有云主機合蔽,那我們需要自己在云主機上搭建并維護這些服務击敌。對于一些資深棧溢出工程師那肯定是沒問題的,但是大部分人都是各有所長拴事,一個好的開發(fā)并不一定是個好的DBA沃斤。
這些IaaS廠商也意識到這個問題,他們會把這些周邊服務統(tǒng)一管理挤聘、運維轰枝,然后賣給開發(fā)者,其實這是個好事组去,IaaS廠商雇用專業(yè)的人士來打磨這些服務鞍陨,通常都要比我們在云主機上手工搭建的要穩(wěn)定、高效从隆、安全诚撵、可用。而IaaS廠商統(tǒng)一處理這些周邊服務之后很容易形成規(guī)模效應键闺,成本可以做得更低寿烟,穩(wěn)定性也更好,雙贏辛燥。
通常的IaaS廠商就是提供這些服務了筛武,當然缝其,像AWS走在行業(yè)前面的巨頭,會提供更多其他的服務徘六,我們姑且不談内边。
IaaS下的開發(fā)
上節(jié)咱們簡單介紹了IaaS提供的服務、產品待锈,那么在這樣的環(huán)境下漠其,開發(fā)人員是怎么利用IaaS快速實現他們的產品原型的呢?
通常一個典型的產品可能包含三個與用戶交互的部分:web端竿音、iOS手機端和屎、Android手機端。而后端通常是有一個nginx前端春瞬,有業(yè)務邏輯部分柴信,比如tomcat中跑的Java code、php-fpm驅動的php code快鱼、gunicorn驅動的Python code颠印,會用到數據庫來做持久化,用到Cache來提高查詢速度抹竹,如果后端有些比較重量級的計算任務可能還會有個rpc服務线罕。
哪部分需要自己搞,哪部分需要IaaS廠商來搞窃判?
- 業(yè)務邏輯相關的代碼肯定是dev來開發(fā)的
- nginx前面通常需要有個四層的負載均衡钞楼,也就是大家熟知的ELB了,這個是IaaS廠商提供
- nginx袄琳、php語言環(huán)境询件、php-fpm(以PHP程序舉例)肯定是sre來搭建并運維了,當然唆樊,如果這個小公司只有一個技術人員宛琅,說不得就要通吃dev、qa逗旁、sre嘿辟、fe、ui片效、ue的所有工作了
- 數據庫红伦、Cache應該由IaaS廠商提供,他們負責維護淀衣、備份昙读、擴容,只要提供給用戶一個連接地址即可
嗯膨桥,看起來IaaS廠商還是幫了我們一些忙的蛮浑,一些系統(tǒng)唠叛、網絡、DBA運維相關的事情用戶是不用操心的沮稚。
接下來這個創(chuàng)業(yè)公司的唯一的技術人員開始著手碼代碼了玻墅。雖然IaaS廠商已經幫忙解決一部分問題了,接下來這個哥們還會遇到哪些問題呢壮虫?腦洞打開……
IaaS之后,缺失的云服務
說缺失可能并不準確环础,因為有些服務已經有些公司在做了囚似,只是目前并沒有與IaaS很好的結合起來
Code托管
代碼放在哪里?這是個問題线得。使用Github饶唤?不太好,因為這是個創(chuàng)業(yè)項目贯钩,原因如下:
- Github是個用代碼交流的開發(fā)者社區(qū)募狂,開源代碼很適合放在上面,但這不代表私有項目也適合放在上面角雷,而且Github私有repo是收費的祸穷,雖然不貴,創(chuàng)業(yè)嘛勺三,能省則省雷滚,特別是有替代服務的情況下
- Github在國外,網絡狀況不是很好吗坚,經常要連vpn才能使用祈远,麻煩
- Github不方便與內部其他平臺(比如編譯平臺)整合,其實這個歸根結底還是網絡惹的禍商源,萬惡的那個啥啊
所以车份,國內出了個gitcafe、出了個git.oschina.net牡彻、出了個coding.net扫沼,稍大一些的公司直接就自己搭建svn服務器或者gitlab服務器
這是一塊蛋糕,親愛的讀者讨便,如果你是做IaaS的充甚,可以嘗試與這些代碼托管服務商合作一下,畢竟霸褒,代碼是一切的開始伴找。
Build平臺
編譯平臺、產品庫废菱,這些名詞對于devops來說再熟悉不過了技矮。這一節(jié)我們就來聊聊這部分話題
代碼已經托管起來了抖誉,那下一步是什么呢?編譯打包衰倦!沒錯袒炉,如果你使用的解釋型語言,比如PHP樊零、Ruby體會可能不深我磁,但如果是編譯型的,比如Java驻襟、Go夺艰、C++,估計就深有感觸了沉衣。code寫好了郁副,要去測試、上線豌习,首先要做的是編譯并打包存谎。
最終的期望是:打成的包自包含Runtime,部署到線上任何一臺機器上都能跑起來肥隆,當然了既荚,前提是這些機器都是相同的操作系統(tǒng),相同的字長巷屿。為啥說要自包含呢固以?因為線上機器環(huán)境千差萬別,操作系統(tǒng)版本可能不同嘱巾、Python版本可能不同憨琳、可能連wget命令都沒有,千萬不能依賴線上環(huán)境旬昭。
做這個平臺的關鍵是指定合理的規(guī)范
最終的發(fā)布包要是什么格式篙螟,包內的文件是怎么個組織方式,meta信息應該放在哪里问拘,啟動腳本應該放在哪里遍略,打好的發(fā)布包放在哪里,應該是一個整包還是散文件骤坐,平臺去哪里拉取用戶的打包產物……發(fā)布包最終是拿來部署的绪杏,故而規(guī)范的制定要考慮與部署系統(tǒng)的結合。
Runtime要提前準備好以提高編配速度
我們剛才說最終的期望是打好的包要做到自包含Runtime纽绍,所以Java的項目需要包含JDK蕾久、Tomcat(或者Resin、Jetty之類的)拌夏,Python的項目要包含Python的語言環(huán)境僧著,還要準備好Nginx之類的履因,這些常用軟件不能在編譯的時候去外網下載,應該提前放到內網或者編譯機上盹愚。
Docker Image & Docker Registry
Docker最近比較火栅迄,我們可以把Docker Image看做是一種發(fā)布包,Docker Registry看做是一種產品庫皆怕。因為Docker Image就是一個自包含的可以在任何部署了Docker的機器上跑起來毅舆。而Dockerfile可以看作是一種打包規(guī)范,類似Heroku和CloudFoundry中的buildpack
這一塊IaaS廠商并沒有提供愈腾,筆者覺得這也是一個可以做的方向朗兵,不知道有沒有創(chuàng)業(yè)公司已經看到商機在這塊發(fā)力了。
Deploy工具
我們說Code已經托管好了顶滩,又有編譯平臺負責打好包了,接下來就是部署了寸爆。作為CI的最后一公里礁鲁,Deploy工具起到了很重要的作用,往QA環(huán)境部署赁豆、往沙盒環(huán)境部署仅醇、往小流量環(huán)境部署、線上全量部署都要用到魔种。
說到底析二,部署就是一個按照某種并發(fā)策略去一批機器上批量執(zhí)行部署腳本的過程
嗯,筆者自認為這句話總結得還算精辟节预,哈哈叶摄,只是不知道有多少人會贊同~
對于單個項目只有幾十臺機器而言,有針對性得寫一個部署腳本安拟,批量ssh到對應機器上跑一下完成部署是沒有問題的蛤吓。但是這不夠規(guī)范,個人搞個人的糠赦,也難以形成業(yè)內標準会傲,推進軟件開發(fā)的步伐,對于幾百臺機器的大項目拙泽,ssh就很難完成了淌山,批量建立信任關系也是一個比較麻煩的事情。
這個時候一個強悍的Deploy工具就派上用場了顾瞻,這個工具要:
- 具備批量去各個機器執(zhí)行腳本的能力泼疑,而且要保證每個腳本不能多執(zhí)行了,不能少執(zhí)行了朋其,每個機器上可能要部署一個agent來支持
- 并發(fā)策略要可調控王浴,比如一個一個來做脆炎?還是每次做2個?5個氓辣?因為不同的服務可承受的同時重啟的實例數目不一樣秒裕,所以這個并發(fā)策略要可配置
- 有既定規(guī)范流程,這個流程是指在單機執(zhí)行的一些步驟钞啸,先干什么几蜻,再干什么,最后干什么等等体斩,我們要去分析抽象出一個通用流程梭稚,能夠滿足大部分項目部署需求
- 單機部署流程可定制,雖然我們已經抽象了一個比較好的通用流程絮吵,但是總有一些特例是沒法用默認方式滿足的弧烤,故而這個流程要可定制,插入用戶自己的特殊邏輯
最后達到的效果就是:用戶要發(fā)起部署蹬敲,只要簡單的指定一些meta信息即可完成暇昂。meta信息可能包括:發(fā)布包地址、機器列表伴嗡、進程啟動賬號急波、部署目錄等等
aws有提供一個叫Deploy的服務,不知道是否就是干這個事情的瘪校。
Config Center
我們在做Build平臺和Deploy工具的時候澄暮,必然要處理配置問題,因為不同的項目配置是不一樣的阱扬,甚至同一個項目泣懊,部署在不同的機器上配置都是不同的。但是對于一個項目而言麻惶,我們期望一次release動作用到的發(fā)布包都是相同的嗅定,不會因為配置不同做成多個發(fā)布包。這個不知道大家有沒有感觸用踩,測試環(huán)境渠退、沙盒環(huán)境、線上環(huán)境通常有自己的配置脐彩,所以有些人就為測試環(huán)境打一個包碎乃、為沙盒環(huán)境打一個包、為線上環(huán)境打一個包惠奸。這種做法在筆者看來是很不好的梅誓。因為QA測試的那個包竟然不是線上用的包!那如何保證不出問題?梗掰!
我們推薦做成一個包嵌言,那就要屏蔽差異,把不同的配置信息抽出來及穗。外部搭建一個Config Center就是一個方案摧茴。
配置信息通常不大,好多人可能很容易想到用Zookeeper實現一個埂陆。不過這篇文章中我們不談具體實現苛白,淘寶有個開源項目叫Diamond也是做類似事情的,大家如果有興趣可以參考一下焚虱,如果沒記錯的話购裙,Google的Borg系統(tǒng)中也是有一個配置中心的。
云主機and服務監(jiān)控
上面提到的幾點主要是針對code和deploy的鹃栽,接下來咱們聊一下監(jiān)控躏率。提到監(jiān)控這個詞,你想到了對什么的監(jiān)控民鼓?cpu禾锤、內存、io摹察、網絡、磁盤倡鲸,嗯供嚎,沒錯,機器基礎監(jiān)控必須要有峭状;進程存活監(jiān)控克滴、端口監(jiān)控、域名監(jiān)控优床,嗯劝赔,針對服務存活性的監(jiān)控,也必須要有胆敞。通常提供云監(jiān)控的IaaS廠商都會提供以上兩類監(jiān)控着帽,夠了么?還有其他需求么移层?
你是否想過http 500次數的監(jiān)控仍翰?url響應時間過長的監(jiān)控?api調用次數過多的監(jiān)控观话?log中Error字樣或Exception字樣過多的監(jiān)控予借?嗯,這些就屬于是一些業(yè)務自定義監(jiān)控了。能提供這種監(jiān)控的IaaS就不多見了灵迫。而實際上秦叛,這是很有需求的,就像我剛才舉的這幾個例子瀑粥,你是dev的話你肯定也想知道吧挣跋?
但是這些監(jiān)控每個服務都不一樣,作為IaaS平臺方利凑,應該從哪里拉取這些監(jiān)控數據呢浆劲?顯然,沒地方哀澈!應該讓app方告訴平臺方pull的接口是什么牌借,或者平臺方直接提供一個push接口,讓app自己去收集數據然后push割按。不管是哪種方式膨报,平臺方都要制定數據格式規(guī)范,比如什么樣的接口才可以被拉取适荣,拉取到的數據應該是什么格式现柠,或者什么樣的數據才能push,push的方式是什么樣的弛矛,諸如此類够吩。
如此一來,我們開發(fā)產品的這些苦逼碼農不但可以了解到我們使用的云主機的運行情況丈氓,服務的存活情況周循,也可以了解到服務的性能情況,穩(wěn)定情況万俗,是不是不錯湾笛?
LB接口化
IaaS廠商剛剛起步的時候,第一個要做的顯然是云主機闰歪;云主機搞定之后呢嚎研?顯然是RDS;RDS搞定之后呢库倘?大部分廠商都會選擇去做LB临扮,因為域名后面直接配置七層server還是有很大的問題,那就是七層server宕機之后無法及時從域名中摘掉教翩,因為dns是有比較久的生效時間的嘛~于是LVS之類的四層負載均衡設備就派上用場了公条,也就是aws中所謂的ELB。
通常IaaS廠商都會提供LB迂曲,但是并不是所有廠商都提供api讓用戶去修改vip對應的rs靶橱,而這點在筆者看來是一個非常重要的功能,最好盡快提供。它有什么用呢关霸?LB已經可以自動摘掉宕機的七層實例了传黄,還不夠?這個api主要是用于做自動遷移的队寇,即:新擴容的rs可以及時加進來膘掰,宕機的rs可以及時摘掉。這個加進來和摘掉的動作要自動化佳遣!故而LB要接口化识埋。
All in Automation
之前我們已經提到需要一個Deploy工具,讓用戶方便得部署他們的服務零渐,快速迭代窒舟,持續(xù)集成。但是在部署的過程中用戶仍然要指定很多信息诵盼,比如要部署的機器列表惠豺,run應用的Linux賬號,部署完成之后還要手工修改ELB的配置风宁,修改vip對應的rs(別怕洁墙,通常是不用修改的,只有個別情況比如擴容的時候才需要)戒财。整個過程比較復雜热监。特別是分配機器列表,如果模塊比較多饮寞,我們?yōu)榱烁玫馁Y源利用通常會選擇混部孝扛,比如io密集型的與cpu密集型的部署到一臺機器上,這樣一來我們要花心思去分配骂际,能不能讓平臺自動化去調度完成?
比較好的用戶使用方式可能是這樣的:
用戶提供發(fā)布包冈欢,提供所有可用的機器列表歉铝,告訴平臺要部署的服務是io密集型的還是cpu密集型的,告訴平臺這個服務要注冊的ELB vip是什么以及這個服務的服務端口是什么凑耻,然后平臺自動去調度部署太示。
平臺可能的做法:
通過監(jiān)控系統(tǒng)收集到該用戶各個云主機的資源利用情況,按照比較好的混部策略香浩,找到比較適合部署這個服務的云主機类缤,部署少量幾個app實例,把這幾個實例注冊到對應的vip上去(LB接口化很重要吧邻吭,嘿)提供服務餐弱,然后監(jiān)控這些實例是否掛掉,如果掛掉了自動拉起,如果實例所在的機器都掛了膏蚓,自動將實例遷移到其他好的云主機上去瓢谢,同時修改vip對應的rs配置,然后監(jiān)控這個vip的流量驮瞧,如果流量太高氓扛,自動擴容,找新的云主機部署新實例论笔,將新的rs加到該vip下采郎。
目前先想到這么多,這是筆者腦袋中的一個不甚成熟的藍圖狂魔,諸位看官有補充的歡迎留言蒜埋。如果看完之后碰撞出了你腦袋中的思維火花,可以選擇打賞我包煙錢毅臊,我不會介意的理茎,嗯?不知道我的支付寶管嬉?哦皂林,就是我的手機號,嗯蚯撩?不知道我的手機號础倍?打電話問嘛……