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