雲代碼的由來
随着MBaaS的發展,取代移動企業應用程式平台的趨勢也越來越明顯。MBaaS系統為了讓企業能友善快捷的開發自己移動應用程式,提供了諸多移動用戶端支援,有最通用的REST API,也有友善移動開發者的軟體開發工具包,還有一定程度的監控和分析服務提供。而對于相對比較複雜的應用程式,開發者有時不想也不必在移動裝置上運作很複雜或很費時或無法實作的業務邏輯,這種需求催生了雲代碼的産生。
雲代碼的願景
想象一下,如果你想要少量結果資訊,但卻必須要向裝置發送大量對象清單,或者調用大量REST API才能完成此項工作時(比如統計彙總操作),這種操作顯然會消耗你大量的帶寬和使用者流量。
想象一下,如果你想要裝置周期性定時完成某個任務或者想在背景一直運作某個任務(比如資源回收垃圾清理),這種操作顯然很不可靠,一方面使用者可能會随時關閉裝置上的應用,另一方面在背景一直運作某個任務顯然也會耗費使用者裝置電量等資源,得不償失。
想象一下,當你需要調用第三方平台API時需要對方回調時比如完成某個支付操作,服務提供商在支付成功後執行回調,你需要根據回調結果完成後續操作比如同步記錄到資料庫中,這種操作在移動應用在沒有自己的後端伺服器時也很難完成。
想象一下,你的某個App應用有iOS,Android,JavaScript等多個裝置平台版本,當你新增一項功能,同一套業務邏輯需要在所有平台做同步開發,當你修改一項功能,同樣需要在所有裝置平台做新版本釋出更新操作,如果産品疊代很迅速那這種頻繁的操作顯然會大大增加移動開發的成本和效率,但效果卻可能不見得很好。
想象一下,當某個使用者注冊了你的應用,你需要對該使用者增加一些資訊來用于統計,或者使用者購買了應用裡的某個商品,你需要收集除訂單外額外的資訊,這類在使用者觸發某些特定操作時會自動額外産生的邏輯(Hook操作),這些Hook操作并不适用在移動端編寫。
伴随移動開發,類似上面的情況多有發生,此時MBaaS系統提供的雲代碼功能就是為移動應用量身定做的解決類似上面問題的方案,雲代碼的願景就是友善移動開發者徹底擺脫伺服器,随心所欲的開發各種移動應用程式。
MaxLeap作為一款優秀的MBaaS平台系統,其雲代碼的功能如何,是如何實作的,又有哪些加分項,接下來将為大家一一揭曉。
MaxLeap雲代碼的功能
有了雲代碼的背景願景,那雲代碼需要提供的基礎功能就很顯然了
- 首先得提供基礎服務和架構,友善使用者開發雲代碼
- 其次得提供代碼托管,能很友善的讓使用者快速部署代碼到雲端運作
- 最後提供日志和相關監控工具,能對線上代碼的錯誤及性能特征有更多了解,以便優化自己的程式
MaxLeap雲代碼的實作
1、讓開發者如何開發雲代碼
如何提供基礎服務和架構來友善使用者開發?由于使用者的開發環境和擅長的開發語言各種各樣,比如使用Java,使用NodeJs,使用Python,使用JavaScript的等等,我們提供對應的各個開發語言的基礎雲代碼SDK,豐富使用者的選擇,降低使用者開發門檻和成本,這樣雲代碼在CloudCode SDK基礎上開發就會非常便捷,這些CloudCode SDK和MBaaS對外提供的移動SDK不同的地方在于它并不在移動裝置上運作,而是在雲端運作。也就是說開發者先要選擇自己喜歡的雲代碼SDK,比如我很擅長JAVA,是以我會選擇cloud-code-java-sdk來開發我的雲代碼,同時雲代碼SDK還要提供本地開發測試架構,總不能讓使用者線上開發調試吧,本地開發本地調試完成後再部署到雲端。當然為了開發者更快的開始,MaxLeap同時提供了Demo和Quick-Start項目來讓開發者更快接觸雲代碼。
2、雲代碼如何為使用者提供服務
開發者在使用雲代碼部署到雲端後該如何通路雲代碼?MaxLeap的雲代碼是通過基礎的REST API來通路,雲代碼SDK負責提供Http服務對外暴露REST API,因為基于Http可以很好的相容不同開發語言,實作跨平台通路,當然這些API不會直接暴露在使用者面前,使用者隻有通過調用MBaaS的雲代碼服務API才能間接通路。
3、雲代碼能為使用者提供哪些服務
不同開發語言的基礎雲代碼SDK其實都具有相同的功能,最重要的是資料存儲服務,CloudCode SDK通過封裝一系列REST API來讓開發者很便捷的通路基礎MBaaS服務。除此之外還要提供雲函數、背景任務、Hook操作、消息推送、日志、安全通路、分布式計數器、分布式鎖等功能。
- 資料存儲服務
通過SDK可以很友善的使用MaxLeap的存儲服務,例如對象的CRUD操作,同時內建了手機行業主流的金币系統。
- 雲函數
運作在MaxLeap雲端的函數,定義好雲函數後可以通過REST API方式來通路,這個API是同步的。同時雲函數提供白名單功能(通過界面設定),友善被其他第三方網絡服務調用。
- 背景任務
同樣是運作在MaxLeap雲端的函數,對于長期運作的任務而言,背景任務非常有用,例如與響應時間較長的外部網站內建或分批發送推送通知。如果您在運作雲函數時經常遇到逾時錯誤,則可以考慮使用背景任務,同時當您部署雲代碼後,可通過背景界面進行計劃任務,你可以計劃一次性任務或者周期性任務,這不但可以友善管理你的背景任務,同時也能清楚的追蹤你的任務狀态。
- Hook操作
Hook用于在對 Cloud Data 進行任何操作時(包括建立,删除及修改)執行特定的操作。例如,我們在使用者注冊成功之前,可以通過beforeCreate Hook,來檢查其是否重名。也可以在其注冊成功之後,通過afterCreate Hook,向其發送一條歡迎資訊。Hook能很好地實作與資料操作相關的業務邏輯,它的優勢在于,所有的業務在雲端實作,而且被不同的應用/平台共享。
- 消息推送
在移動應用中,為每個用戶端使用者推送系統消息或定制消息必不可少,通過該功能開發者可以很便捷的将消息推送到所有或指定裝置上。
- 分布式計數器/鎖
雲代碼在雲端是一個分布式應用,提供計數器、鎖相關的功能以便多個執行個體之間可以共享同一份資料。
- 日志
提供Logging功能,以便您能記錄Function,Hook或者Job在運作過程中出現的資訊。
- 指令行工具
可以友善使用者雲代碼項目的上傳,部署,停止及版本管理。
4、雲代碼該如何管理
雲代碼作為在雲端部署的代碼,MaxLeap是如何管理它們的呢?在這項重中之重方面我們可能會遇到下面這些問題:
- 每個開發者的環境不同,作業系統也不相同,如何降低搭建各種環境的成本以及降低對作業系統的依賴、降低硬體要求和應用環境之間耦合度同時降低虛拟化消耗?
- 管理的應用可能成千上萬,但是伺服器資源就那麼多,該如何對每個應用實作虛拟化來整合應用和伺服器降低成本?
- 每個應用的重要程度也不同,有重度使用者需要高可用高性能的服務,有低度使用者可能一天也不會有幾個請求,資源該如何配置設定?
- 使用者的代碼部署在雲端,如何保證使用者的應用代碼安全?
- 使用者代碼服務如何做到高可用,出現故障該如何轉移,如何做到服務不間斷,新釋出的代碼出現異常該如何復原?
基于上面遇到的問題,我們把使用者的雲代碼作為一個松耦合的單個服務,也就是現在流行的微服務架構,通過docker來實作對微服務容器化,因為docker本身就是源于Paas,在MBaaS系統也非常适用,我們不用為每個雲代碼應用開啟一個虛拟機來降低硬體要求和應用環境之間的耦合度,這能大大降低虛拟化消耗,降低成本,而且docker還能為應用提供一個從開發到部署上線都一緻的環境,非常便于管理代碼的流水線,讓我們可以對雲代碼從開發到釋出部署簡單可靠的控制。同時Docker隔離應用的能力非常适用于使用者的雲代碼,能讓我們比通過虛拟機更好的整合雲代碼應用和伺服器,基于docker,我們能為每個不同的雲代碼應用建立隔離的環境,并為他們配置設定指定的服務端口、記憶體資源等來隔離應用。
在我們看來使用者每次的代碼釋出都是一個建構鏡像并推送鏡像到私服上的過程,每次代碼部署都是從私服上擷取鏡像并啟動一個容器的過程,每次停止部署都是一個容器解除安裝的過程,每次更新代碼都是一個重新生成不同标簽的應用鏡像的過程。使用者每次上傳釋出雲代碼都需要為它指定一個版本,不同的版本會生成不同的鏡像标簽,可以同時部署多個版本,但我們做了限制,最多隻能同時釋出2個版本,我們稱之為灰階釋出,這是為了能讓你的代碼能平滑過渡更新,在灰階釋出過程中使用者需要設定版本負載均衡比重,以做到服務不間斷,基于版本控制你可以復原你的代碼,你可以選擇你釋出過的任意版本進行部署,這真的非常友善。
對于使用者的雲代碼鏡像、啟動的容器、部署的政策以及容器所在的主控端我們會有一個專門的CloudCode-Manager服務來進行管理,我們稱這個服務為hydra(海德拉)。它希臘神話中的九頭蛇,傳說它擁有九顆頭,其中一顆頭要是被斬斷,立刻又會生出兩顆頭來,在這裡我們寓意使用者的雲代碼可以達到高可用,如果使用者部署的任何一個雲代碼執行個體出現故障達到服務不用,系統會自動在其他主控端上重新啟動一個相同執行個體。為了達到高可用、故障轉移,雲代碼SDK需要提供心跳接口,在使用者部署雲代碼後每隔一段時間hydra都會做心跳檢查,檢查失敗重試一定次數後便認為該服務已經失效,我們會在另一台主控端上重新部署一個和故障執行個體一模一樣的執行個體,然後再解除安裝故障執行個體,如果解除安裝故障執行個體失敗,比如故障執行個體所在的主控端發生當機,那麼該故障執行個體會永久成為一個孤島執行個體等待被強制回收。如果應用的雲代碼被重度使用超過負荷可以随時擴容,或者通過縮容來較少成本,通過任意擴容和縮容也就是通過部署容器任意執行個體數量來真正達到高可用,最常用的使用場景是商家在做活動時有通路高峰可以快速增加執行個體資源來減少壓力,日常時則減少執行個體以低成本運作。
通過docker來整合應用和伺服器,一台主控端上可能部署了上百個容器應用,那應用是如何分發的呢,在雲代碼SDK中我們提供了REST服務,比如雲函數、背景任務、心跳等API,所有應用的這些REST服務在啟動後都是監聽在容器的8080端口,容器需要允許外部通路就必須要映射容器端口到主控端,是以在應用分發過程中,主控端的端口管理非常必要,我們使用mysql來存儲所有主控端的資訊,包括所有提供給雲代碼容器使用的可用端口,通過樂觀鎖來保證端口的并發配置設定,啟動任意雲代碼容器時都會配置設定一個映射端口給容器,同時在zookeeper中同步應用的雲代碼服務位址提供給MBaaS雲代碼服務使用。這個過程使用事務來保證容器啟動和資料庫資訊的一緻性,同時使用zookeeper分布式鎖來防止同一個應用被同時操作。雲代碼服務的REST層實時監控zookeeper中雲容器通路位址資訊變更,通過hosting形式提供路由功能,通過負載均衡算法選擇可用位址來通路主控端上的雲代碼達到分流效果,這樣就能做到簡單有效的應用分發。
上面我們說到雲代碼容器通過端口映射來允許外部通路,但考慮到使用者的代碼安全,并不是任何機器都可以通路雲代碼容器,這就需要一個網絡安全體系來對使用者的通路和網絡進行限制。在網絡隔離安全方面,我們在Docker的标準網絡橋接接口docker0上啟用核心防火牆iptables規則來限制Docker容器的源IP位址範圍與外界通訊,所有的雲代碼主控端隻能由zcloud和hydra服務所在的機器通路,而雲代碼通路zcloud内部服務需要通過反向代理實作。
在主控端和容器之間安全隔離方面,通過通路控制的安全政策,使用selinux配置Linux核心安全子產品,進而實作強制性的通路控制(MAC)用以将程序限制在一套有限的系統資源或權限中。在容器與容器之間通過cgroups防止通過耗盡系統資源引發拒絕服務(DoS)攻擊,比如限制容器的CPU使用、記憶體使用、存儲使用。
5、雲代碼該如何監控
使用微服務容器化雲代碼能為應用開發者省去部署和維護方面的負擔,但代價是一定程度上減弱了線上環境的透明性,為了能對線上代碼的錯誤和性能特征有更多了解以便優化自己的代碼或者擴容、縮容來達到水準擴充,我們需要給很好的監控雲代碼。
1、首先是日志資訊的收集,雲代碼的系統日志、使用者的日志這些都需要收集起來提供給使用者檢視,MaxLeap的雲代碼使用主流的Logstash+elasticsearch來完成日志收集工作,我們會在每台主控端上啟動一個logstash-forwarder服務作為shipper來收集指定的雲代碼日志,Logstash彙聚日志後轉發到ES存儲。
2、其次是對容器資源的監控,Docker容器通過namespace做資源隔離,通過cgroup來做資源限制,我們有個專門的docker-monitor服務來監控所有主控端上雲代碼容器的名額,它會周期性擷取已注冊的主控端上所有雲代碼容器的cgroup stats,收集名額包括CPU MEM IO等,然後将資料PUSH到ES裡。
3、最後是展示給使用者,MaxLeap通過背景界面的方式展示出所有容器執行個體的性能和狀态,還有部署的雲代碼版本所有的日志資訊,使用者可以很直覺的了解到自己的雲代碼有什麼錯誤的資訊,在什麼地方有瓶頸,該在哪方面優化代碼。而我們内部會通過Kibana來展示,并通過Nagios來報警。
MaxLeap雲代碼的衍生-雲容器
有客戶看到這裡說:你說了那麼多,我就是不想用你的雲代碼SDK來寫,熟悉你的SDK都要花費好長時間,用看官方文檔頭都大了,我就想用關系型資料庫,我就是想用我自己寫的後端服務或者之前公司已經寫好的程式,咋辦?嘿,MBaaS系統的願景是讓使用者完全擺脫伺服器,但遇到這種已經有自己伺服器和資料庫并大量線上使用的客戶讓他們選擇MBaaS系統便得仔細考量是否值得了。考量到這類需求,MaxLeap在雲代碼的基礎上衍生出了雲容器的概念,它是可以幫助使用者部署及運維其後端應用程式的代碼托管服務,使用者隻需要提供服務端的業務邏輯,包括靜态網站或者動态應用程式,而服務端的高可用、多執行個體、負載均衡、不中斷服務的平滑更新等都由雲容器提供支援。沒錯,雲代碼有的功能它都可以有,雲代碼沒有的功能它也有,一個是資料源功能,很多企業客戶内部使用的資料庫都是mysql這種關系型資料庫,讓他們一下切換到MBaaS上的NoSql資料庫會很不放心,特别對事務要求很嚴格的業務邏輯,人家可能一看到你的資料庫是使用Nosql就放棄了,能很友善的遷移也不行,就是這麼直接,雲容器的資料源功能則會幫讓他們放下很大一部分顧慮,它可以讓使用者使用并管理自己的關系型資料庫,而另一個二級域名功能可以讓使用者在部署雲容器後可以直接通路他的雲服務。作為雲代碼的更新版,雲容器的底層架構都是基于雲代碼的實作,這完全降低了使用者Dev&Ops上的難度。由于篇幅原因,更多雲容器相關的資訊本篇文章不再贅述了。
MaxLeap雲代碼的展望
看到這我們發現MaxLeap的雲代碼、雲容器的架構基本都是圍繞docker容器這個生态圈來實作的,那麼如何更好的維護和優化這個生态圈将是我們将來的重中之重,在這裡我們給出一些我們未來一段時間将要實作和優化的關鍵資訊:
- 所有容器資源通過Mesos申請
- 所有容器生命周期通過Marathon管理
- 更智能的資源配置設定機制,更智能的壓力監控實作自動擴容/縮容
- 使用者雲代碼托管方式支援git等第三方倉庫
- 使用者上傳雲代碼、雲容器支援增量上傳來減少等待時間
- 更多容器安全方面的優化
- 更多雲代碼/容器操作的Dev&Ops自動化
- 更多基建架構方面的調整優化
MaxLeap更強大更優秀的雲代碼/雲容器服務敬請大家期待。