摘要:本文將結合馬蜂窩容器化平臺賦能前端應用構建的實踐經(jīng)驗,介紹整個平臺背后的設計和實現(xiàn)原理,取得的一些效果及問題的優(yōu)化方案。如果使用容器化平臺就不會出現(xiàn)這方面的擔憂。
容器對前端開發(fā)真的有用嗎?答案是肯定的。
最初當我向公司的前端同學「安利」容器技術的時候,很多人都會說:「容器?這不是用在后端的技術嗎?我不懂啊,而且前端開發(fā)用不上吧。」
但其實,今天我們討論的「前端」已經(jīng)不是傳統(tǒng)意義上的「前端」, 首先體現(xiàn)在終端類型的多樣性,比如 iOS,Android,小程序等;另外,伴隨著 Node.js 等技術的興起,前端開發(fā)的邊界也在逐漸服務端延伸。來到大前端時代,如何以工程化、服務化和自動化的方式來進行應用開發(fā),實現(xiàn)業(yè)務的持續(xù)迭代、高可用、高并發(fā)是每一個成功的互聯(lián)網(wǎng)產(chǎn)品不斷探索的事情,而漸為成熟的容器技術大大提高了這個過程的效率。
本文將結合馬蜂窩容器化平臺賦能前端應用構建的實踐經(jīng)驗,介紹整個平臺背后的設計和實現(xiàn)原理,取得的一些效果及問題的優(yōu)化方案。
容器與前端的結合點一般來說前端的開發(fā)流程是這樣的:創(chuàng)建服務/項目 → 本地開發(fā) → 開發(fā)環(huán)境測試 → 生產(chǎn)環(huán)境測試? → 生產(chǎn)灰度 → 上線。
基于容器化平臺進行前端開發(fā)的優(yōu)勢在于,前端和后端完全分離,我們只需要關注前端的項目構建,而不需要和后端代碼一起打包。每個構建版本及每個訪問規(guī)則也都是獨立的,一個版本構建失敗并不影響其他版本的構建及訪問。
那么,容器和前端的結合點在哪里?容器的優(yōu)勢在前端應用研發(fā)的哪個環(huán)節(jié)發(fā)生作用?我們可以從開發(fā)、測試、生產(chǎn)這三個階段分別來看。
?開發(fā)環(huán)節(jié)容器消除了線上線下的環(huán)境差異,保證了應用生命周期的環(huán)境一致性標準化。而對于前端開發(fā)來說,要完成的任務往往是完成內(nèi)容的呈現(xiàn)和響應用戶的輸入,處理的是 HTML、JS、CSS 等靜態(tài)資源,文件直接發(fā)送到客戶端,不需要一個運行環(huán)境,這里好像用不上容器。
那 Build 的時候呢?畢竟不同的項目是用不同的 Node 版本在做構建,不同的容器可以進入不同的 Node 版本,這樣就不會污染本機的 Node 環(huán)境。但其實沒有容器,前端還可以用 NVM 去管理 Node 版本,切換起來很隨意,也就是一兩行命令就能搞定的事情。而且本地開發(fā)很方便,看起來真的沒有必要用容器。
可以說,容器本身并沒有幫助前端在開發(fā)階段變得更加便利。因此如果對容器技術不熟悉,開發(fā)階段沒有必要非要用容器。
測試環(huán)節(jié)過去我們用虛擬機進行測試的一個常見的方案是,前端研發(fā)把自己的代碼上傳到虛擬機的一個目錄下,QA 可以直接通過域名進行測試。但問題是,公司有很多的產(chǎn)品線,可能會存在很多項目同時提測的情況。虛擬機對系統(tǒng)資源的消耗比較大,數(shù)量有限,并且難擴容,影響測試效率。
如果使用容器化平臺就不會出現(xiàn)這方面的擔憂。因為容器非常輕量,消耗低、啟動快,可以迅速擴容,不用擔心不夠用的問題。
生產(chǎn)環(huán)節(jié)容器的另一個優(yōu)勢是它可以實現(xiàn)應用程序的版本控制。比如我們在上線之后發(fā)現(xiàn)版本有問題需要回滾,這種情況不可避免,傳統(tǒng)的做法是通過 Git 或者 SVN 回滾,一旦合入的代碼想回退或者拆分就很難操作,而且重新部署也很耗時。
基于容器化的平臺,我們可以直接通過流控,把流量切到舊的版本上去,幾需要幾秒鐘的時間,回滾效率大大提升。
再如,前端性能的一個重要指標是頁面加載時間,如果出現(xiàn)首頁白屏是非常破壞用戶體驗的,特別是在做活動的時候,我們把幾乎所有流量都引導到活動頁,出現(xiàn)白屏會非常讓人抓狂。找到運維排查之后發(fā)現(xiàn)有臺服務器掛了,只能通過重啟來解決。但是重啟機器存在很多不確定性,有可能這臺機器就起不來了,這種情況很常見。
但如果運行在容器化平臺上,一個容器就是一個進程,一臺機器如果宕機,集群會快速從另外一個節(jié)點把服務拉起,而且是秒級的,基本不用擔心用戶的訪問會出現(xiàn)問題。
總結來看,容器與虛擬機相比主要的優(yōu)勢體現(xiàn)在可以實現(xiàn)快速擴容、秒級回滾和穩(wěn)定保活。因此容器化對于前端開發(fā)來說,更重要的意義是能夠保證服務的快速迭代,以及線上服務的穩(wěn)定性。
前端需要了解的容器知識點通過上面的介紹,相信大家已經(jīng)對容器技術為前端開發(fā)帶來了哪些變化有了一些感受。那么為了更好地應用這項技術,前端同學也應該掌握一些容器的基礎知識。
?容器是什么首先我們來看容器到底是什么,它為什么輕量、高性能。通過下面這張圖片,我們可以將虛擬機和容器進行一個更加直觀的對比:
虛擬機通過在物理服務器上層通過運行 Hypervisor 模擬硬件系統(tǒng),來提升服務器的能力和容量。每個虛擬機中有一個內(nèi)核,運行著不同的操作系統(tǒng),啟動之后會做進程管理、內(nèi)存管理之類的事情。但對于前端應用的構建來說,可能只是需要一個 Nginx 做靜態(tài)服務器,這種場景下使用虛擬機就太重了。
容器之所以輕量,是因為容器沒有 Hypervisor 層和內(nèi)核層,每個容器都共享宿主機的內(nèi)核和系統(tǒng)調(diào)用。因此一個容器內(nèi)包含的僅僅是一個程序運行所需要的最少文件,啟動容器就是啟動進程,對資源的開銷更小,維護起來更簡單。
鏡像、容器和 Docker?這是大家在聊到容器技術的時候經(jīng)常會提到的三個詞,下面來說下它們各自的概念以及之間的聯(lián)系是什么。
鏡像:可以簡單理解為一層層文件系統(tǒng)的集合,或者說一些目錄的集合。比如對于我們的前端代碼,最下面那層目錄可能是 Nginx 運行所需要的二進制,然后在上面再加一層目錄是我們的代碼,比如說 index.html。這個鏡像分層所有的分層生成以后,都是只讀的,每一層文件不可修改。
容器:其實就是在上面的目錄上再加一層目錄。但它其實是一個空目錄,區(qū)別就在于容器最上面一層是可讀可寫的,也就是說容器 = 鏡像 + 讀寫層。
比如我如果想修改之前的 index.html ,是通過把新的版本累加在之前的鏡像上。也就是說生成容器以后,所有的變更都發(fā)生在頂層的鏡像可寫層,下面的這些層是不允許往里面寫東西的,但是可以累加,就像堆積木一樣,一直加上去,而原來的鏡像不會被容器修改,這也是鏡像可以被多個容器共享的原因。?
Docker:容器技術其實早就存在,Docker 是用來實現(xiàn)容器化技術的一種工具,也是目前業(yè)界最通用的一種方式,來幫我們制作鏡像,然后把鏡像運行成為容器并管理起來。
容器化平臺如何為前端賦能介紹完簡單的概念,我們就和大家一起來看馬蜂窩容器化平臺的整體架構,我們是如何為前端賦能,以及賦予什么樣的能力。
我們基于 Docker 和 Kubernetes 搭建了容器云平臺,將應用的構建、部署、資源調(diào)度、應用管理等能力抽象出來,以服務的方式提供給研發(fā)人員,提升線上服務的穩(wěn)定性和研發(fā)效率。下圖從應用的角度出發(fā),展示了前端應用在容器化平臺的生命周期:
應用中心應用是容器云平臺的基本操作對象。云平臺一個非常大的好處是屏蔽了項目的類型,不分前端或后端。于是在應用的外殼下,不管是前端的代碼,還是后端的代碼,都可以享受同樣的服務。比如傳統(tǒng)意義上應用在后端的限流、熔斷、服務治理等能力一樣可以賦予前端,使前端同學聚焦在業(yè)務開發(fā)上,而不需要關注底層的實現(xiàn)。
這是應用中心的一個創(chuàng)建頁面,只需要幾步,一個應用就可以創(chuàng)建完成,并且托管到我們的云平臺上:
版本管理創(chuàng)建完應用之后就要開始構建版本。通過使用容器,我們將應用程序、配置和依賴關系等打包成一個個代碼鏡像,然后去告訴線上服務器怎么讓它們用容器化的方式運行起來。因此版本管理包含代碼鏡像和運行時配置兩部分內(nèi)容。
1. 代碼鏡像
我們使用基于 Pipeline + Docker 的 Drone 作為 CI 工具,它非常靈活,容易擴展。Drone 的靈活性體現(xiàn)在 Pipeline 的配置上,可以通過設置 .drone.yml 文件的方式在項目中控制構建鏡像的過程。?
為了更好地支持公司級別的應用,我們向鏡像注入一些內(nèi)部經(jīng)常用到的包來構建一個通用的基礎鏡像。在構建的同時會做一些 CI,比如單元測試、漏洞檢測等。?
2. 運行時配置
運行時配置分成 Nginx 配置和部署運行時的配置兩個部分
(1)Nginx 配置
Nginx 配置主要針對 Node 前端項目來說。將 Nginx 配置開放給應用有這么幾點好處:
前端同學可以自己去配置 history 模式,不需要再去找服務端來配合。
自定義多個 location。在面對多頁應用時,可以通過配置 Nginx 把請求轉(zhuǎn)發(fā)到指定的入口文件,實現(xiàn)指定路由。
自定義 cache 緩存策略。緩存策略選擇更靈活,提升用戶體驗,降低服務器處理請求的壓力。
(2)部署運行配置
部署運行配置是要告訴系統(tǒng)平臺要如何運行版本包。這里其實也就為后續(xù)部署到 Kubernetes KVM 宿主機等多種平臺留好了擴展。
總結來看,在版本管理的部分我們實現(xiàn)了以下幾點能力:
配置文件驅(qū)動,一個應用多份靈活好擴展
Nginx 配置等開放給應用,遵循 DevOps 思想,高效賦能
標準化版本產(chǎn)物,一處構建,處處運行
部署管理接下來我們需要把已經(jīng)構建好的版本包部署到集群上去運行。
在線上可能會有許多臺機器,V1、V2、V3 指的是各種版本。這個版本可以有多個實例。如果服務出現(xiàn)故障,我們主要通過兩種方式來保證穩(wěn)定高活:
高效調(diào)度:通過 Kubernetes 調(diào)度器將指定運行的容器調(diào)度到資源滿足要求、最合適的節(jié)點上去
多副本支撐:自動部署一個容器應用的多份副本,并持續(xù)監(jiān)控。如果容器掛掉自動啟動副本
結合我們之前說到的主頁白頁的例子具體說明,我們會在容器化平臺上持續(xù)看管容器,如果服務掛了,就在迅速在別的節(jié)點上啟動起來。這里需要注意的是,「多份」不僅僅是說在兩臺機器上啟動就叫多份,如果兩臺機器都在一個機柜上,甚至在一個機房里,那么啟動多份也沒有意義。
到這里,我們已經(jīng)把服務部署到線上,并且實現(xiàn)穩(wěn)定運行。但是完成部署,不代表用戶就能訪問,也不代表就能訪問到正確的版本,所以接下來就到服務治理的環(huán)節(jié)。
服務治理服務治理是一個比較大的概念,可以應用的場景也很多。它的其中一個內(nèi)容是讓用戶訪問到指定的一線上版本。
技術方案
首先介紹下實現(xiàn)原理:
我們采用的是一個 支持 xds 協(xié)議的網(wǎng)關。當新的配置通過 xds 協(xié)議推送給網(wǎng)關時,它就會自動進行熱更新、熱重啟,然后去適應新的配置。比如說開始網(wǎng)關指向的是 V1 版本,如果我們現(xiàn)在希望指向 V2 版本,只需要把最新的配置通過 xds 協(xié)議推送給網(wǎng)關,它就會應用新的配置,通過這種方式就可以將指定版本部署到線上。
推送這里我們用的是 Pilot 組件,并針對推送速度進行了優(yōu)化。Pilot 組件會不斷監(jiān)聽數(shù)據(jù),發(fā)現(xiàn)有變更后就會取出。
應用場景
針對這種設計,我們主要將其應用在三個場景中:回滾、分流和 ABTest。
1. 回滾
所謂回滾其實就是流控,比如一開始網(wǎng)關指向的是 V2 版本:
如果發(fā)現(xiàn)有問題,我只需要給網(wǎng)關推送一個新的配置,它就可以指向之前那個版本,非常快速:
2. 分流
分流主要應用在文章開始說到的提測場景中。過去使用虛擬機,由于不同的虛擬機有不同的域名,前端同學在測試的時候要么就是為了適配虛擬機去修改代碼,要么就是需要測試同學或者產(chǎn)品同學自己去修改自己本機的 host,非常不方便。
而使用容器化的方式,如說現(xiàn)在默認訪問的是 V2 版本,但我們現(xiàn)在需要測試 V1 或 V3 版本,就可以推出一個配置給網(wǎng)關,告訴它說如果請求里面的 cookie 含有標識 V=V1,就把請求轉(zhuǎn)發(fā)至 V1 版本;同樣如果 cookie 包含 V=V3,就將請求轉(zhuǎn)發(fā)到 V3, 所有的轉(zhuǎn)發(fā)都在網(wǎng)關層完成。
為了使服務更易用,我們提供了一個插件去自動識別云平臺部署的服務和版本。QA 和 產(chǎn)品同學在測試的時候,只需要點選版本就可以,系統(tǒng)會自動完成 cookie 注入。然后向服務端發(fā)送請求時,網(wǎng)關就會發(fā)現(xiàn)這個攜帶了某個版本的 cookie,自動完成轉(zhuǎn)發(fā):
3. ABTest
同樣的原理,我們可以通過配置指定用戶的 UID,控制用戶去訪問 ABTest 中的不同版本,這里支持的方式有很多,比如注入 cookie、不同的 head 頭、不同的請求方式等等,非常靈活。
以上是服務治理的內(nèi)容。總的來說,我們能夠自動化部署訪問規(guī)則,可能只需要前端同學做一個 git-push tag 的操作,就已經(jīng)打好版本并部署到開發(fā)環(huán)境甚至是生產(chǎn)環(huán)境,而整個過程對于平臺的使用者來說是無感知的:?
自動化部署訪問規(guī)則,完整 CI/CD
靈活的分流策略,帶來秒級回滾,灰度,abtest 等功能
結合 chrome 插件,體驗流暢
以上介紹了基于容器化云平臺我們可以為前端賦予哪些能力。經(jīng)過一些時間的探索,目前我們的流程已經(jīng)比較通暢,但不可避免還是會遇到一些問題。
那些年我們遇到的?404 1. 上線后,發(fā)現(xiàn) js 訪問404? ? ? ? ? ? ? ? ?這種情況對用戶體驗來說非常糟糕。經(jīng)過排查后我們發(fā)現(xiàn)問題出現(xiàn)在為了做到高可用,我們的網(wǎng)關配置了多個。
因為網(wǎng)關的轉(zhuǎn)發(fā)配置是通過推送下發(fā)的,多個網(wǎng)關之前就會存在時間差。有的網(wǎng)關先收到新的推送,有的后收到。當用戶的請求打到了其中一個網(wǎng)關拿到了一個 html,會告訴它應該訪問哪個 hash 的 js。但如果不巧的是 hash 的 js 卻訪問到了另外一個網(wǎng)關,然后轉(zhuǎn)發(fā)到另外一個版本,也就是另外一個容器,那么 hash 值肯定就不一樣了,找不到對應的文件,導致 404。
這個問題不僅云平臺會存在,只要是分布式的部署方案都可能存在時差的問題。我們的解決方案是讓所有網(wǎng)關都連接到同一個 Pilot。因為網(wǎng)關的數(shù)量是有限的,這時配置的下發(fā)就是由一個組件去負責推送所有的網(wǎng)關,因為 xds 協(xié)議本身是基于 GRPC 實現(xiàn)的,是一個長連接的操作,所以速度非常快。當由一個節(jié)點去做推送,所有網(wǎng)關接收到配置的時差可以控制在在毫秒間,幾乎沒有影響。也就是 A 網(wǎng)關接收到新配置的同時,基本上 B 網(wǎng)關也已經(jīng)接收到新配置,這時候所有請求無論打到哪個網(wǎng)關,他們都會指向同一個版本,這個時候線上就不會再出現(xiàn) 404 的請求。
2. 灰度環(huán)境,js 訪問 404之前說到,我們的灰度方案是應用插件做 cookie,理論上來說只要 cookie 的配置正確,就可以轉(zhuǎn)發(fā)到指定的版本上去。那么既然我的 html 已經(jīng)沒問題了,為什么 js 還會出現(xiàn) 404??
排查后發(fā)現(xiàn),因為 js 請求的時候有一個標簽叫「匿名標簽」,如果我們在用 js 的時候打了匿名的標簽,瀏覽器在發(fā) js 請求時就不會攜帶任何身份的標識,網(wǎng)關就會認為訪問到一個默認版本,也就是線上的版本,這個時候如果請求再到 V2 版本就會 404。?
近期規(guī)劃 1. 盡可能釋放構建 Pipeline目前我們構建鏡像的方式主要是用 npm install 和 npm run build 兩個命令。之后我們會盡可能去釋放 Pipeline,包括基礎鏡像、Node 版本等,讓前端同學可以實現(xiàn)更多自定義的需求。
2. 優(yōu)化構建和部署時間目前我們構建鏡像的方案沒有很好地利用 Docker 的緩存機制,因此會影響構建的時間。我們目前也在做優(yōu)化,盡可能減少甚至消滅大部分 npm install 的時間和 build 的時間。
3. 釋放監(jiān)控告警能力目前我們已經(jīng)完成了一部分監(jiān)控告警能力的建設,主要是由平臺維護團隊在使用,去監(jiān)控 QPS 狀況、服務是否穩(wěn)定,有沒有重啟等,團隊內(nèi)部也會收到很多告警。但我們認為這種報警其實更應該發(fā)送給服務的負責人,后面我們慢慢要將這部分能力釋放出來,并且不斷完善和優(yōu)化告警規(guī)則。
總結最后簡單總結:
容器化之后到底給前端賦能了什么?
提高測試效率
服務更加穩(wěn)定,運維高效
馬蜂窩云平臺如何進一步給前端賦能?
應用中心:一步上云,無差別享受云平臺帶來的服務
版本管理:實踐 DevOps思想,賦能 Nginx 配置;配置驅(qū)動,靈活好擴展?
部署管理:智能調(diào)度,穩(wěn)定高活?
服務治理:秒級回滾,秒級恢復,灰度訪問,ABTest等眾多功能
目前我們在如何通過容器化的方式幫助前端完成應用研發(fā)有了一定的探索,并且通過云平臺的方式上做到更進一步的賦能,希望能帶給大家一些技術思維上的啟發(fā)。
本文作者:周磊,馬蜂窩旅游網(wǎng)基礎平臺服務化研發(fā)工程師。
(題圖來源于網(wǎng)絡)
關注馬蜂窩技術,找到更多你想要的內(nèi)容
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/104897.html
摘要:本文將結合馬蜂窩容器化平臺賦能前端應用構建的實踐經(jīng)驗,介紹整個平臺背后的設計和實現(xiàn)原理,取得的一些效果及問題的優(yōu)化方案。如果使用容器化平臺就不會出現(xiàn)這方面的擔憂。 容器對前端開發(fā)真的有用嗎?答案是肯定的。 最初當我向公司的前端同學「安利」容器技術的時候,很多人都會說:「容器?這不是用在后端的技術嗎?我不懂啊,而且前端開發(fā)用不上吧。」 showImg(https://segmentfau...
摘要:本文將結合馬蜂窩容器化平臺賦能前端應用構建的實踐經(jīng)驗,介紹整個平臺背后的設計和實現(xiàn)原理,取得的一些效果及問題的優(yōu)化方案。如果使用容器化平臺就不會出現(xiàn)這方面的擔憂。 容器對前端開發(fā)真的有用嗎?答案是肯定的。 最初當我向公司的前端同學「安利」容器技術的時候,很多人都會說:「容器?這不是用在后端的技術嗎?我不懂啊,而且前端開發(fā)用不上吧。」 showImg(https://segmentfau...
摘要:大交通研發(fā)質(zhì)量體系建設為了幫助用戶更好地完成消費決策閉環(huán),馬蜂窩上線了大交通業(yè)務,為用戶提供購買機票火車票等服務。 質(zhì)量是決定產(chǎn)品能否成功、企業(yè)能否持續(xù)發(fā)展的關鍵因素之一。如何做好質(zhì)量體系建設,這是個比較大的話題,包含的范圍很廣,也沒有固定的衡量標準。 打開一個互聯(lián)網(wǎng)公司招聘網(wǎng)站,搜索「測試工程師」崗位時,你會發(fā)現(xiàn)幾乎全部 JD 都包含一條要求「建設或者參與建設所負責業(yè)務的質(zhì)量體系」。...
摘要:大交通研發(fā)質(zhì)量體系建設為了幫助用戶更好地完成消費決策閉環(huán),馬蜂窩上線了大交通業(yè)務,為用戶提供購買機票火車票等服務。 質(zhì)量是決定產(chǎn)品能否成功、企業(yè)能否持續(xù)發(fā)展的關鍵因素之一。如何做好質(zhì)量體系建設,這是個比較大的話題,包含的范圍很廣,也沒有固定的衡量標準。 打開一個互聯(lián)網(wǎng)公司招聘網(wǎng)站,搜索「測試工程師」崗位時,你會發(fā)現(xiàn)幾乎全部 JD 都包含一條要求「建設或者參與建設所負責業(yè)務的質(zhì)量體系」。...
摘要:如何在新的技術背景下讓前端數(shù)據(jù)采集工作更加完善高效,是本文討論的重點。具體來說,我們對前端的數(shù)據(jù)采集具體主要分為路由切換性能資源錯誤日志上報路由切換等前端技術的快速發(fā)展使單頁面應用盛行。 隨著業(yè)務的快速發(fā)展,我們對生產(chǎn)環(huán)境下的問題感知能力越來越關注。作為距離用戶最近的一層,前端的表現(xiàn)是否可靠、穩(wěn)定、好用,很大程度上決定著用戶對整個產(chǎn)品的體驗和感受。因此,對于前端的監(jiān)控不容忽視。 搭建一...
閱讀 2622·2023-04-26 00:07
閱讀 2431·2021-11-15 11:37
閱讀 638·2021-10-19 11:44
閱讀 2163·2021-09-22 15:56
閱讀 1716·2021-09-10 10:50
閱讀 1497·2021-08-18 10:21
閱讀 2565·2019-08-30 15:53
閱讀 1630·2019-08-30 11:11