網易智慧企業 Node.js 實踐(2)| 平滑釋出和前端程式碼
健康檢查
前文提到我們通過閘道器把流量轉發到 Node 應用,那閘道器是如何確定 Node 應用的可用性呢?
如果 Node 應用在釋出的過程中也把流量轉發過來,就會導致請求失敗,所以我們的閘道器會對 Node 應用做一個健康檢查,要首先確定 Node 應用是健康的,也就是可以對外服務的。具體來說就是閘道器會每隔30秒調一下 Node 應用的健康檢查的 HTTP 介面,如果介面返回的 code 是200,那就表示 Node 應用是可用的,使用者的請求在下次檢查之前都會轉發過來,如果返回其他 code,表示應用不可用,請求就不會轉發過來。過30秒再重複這個過程。 【示意圖】
這個方案實現起來非常簡單,只要再 Node 新增個能正常請求的 HTTP 介面即可,比如我們用的介面 /health/check
它的 controller 內就 this.ctx.body = 'OK'
就可以了。如果 Node 應用正常啟動,可以接受使用者請求,那麼這個介面返回 code 就會是200,如果這個介面不能正常訪問,返回的code不是200,那麼也意味著整個應用是不能訪問的。
那上面這個方案就沒有問題了嗎?肯定是有的,比如我們在釋出時候,首先要讓 Node 應用下線,如果恰好 Node 應用剛被健康檢查通過後就下線了,那麼就會導致後面30秒內轉發到 Node 應用的流量訪問失敗,所以我們有了升級方案-平滑釋出。
平滑釋出
平滑釋出就要跟釋出系統進行配合了,就是我們在釋出應用的時候釋出系統會自動呼叫 Node 應用的下線介面,釋出完成之後會呼叫 Node 應用的上線介面,這樣就可以通過一個全域性變數控制應用的狀態,而這個狀態是和應用的真實狀態沒有關係的。呼叫下線介面後,應用狀態置為下線,然後等待一段時間才真正讓應用下線,所以如果這時有流量進來應用依然可以正常服務。 【示意圖】
邏輯很簡單,但是實現的時候要考慮到 Egg.js 的多程式模型,Egg.js 一般根據伺服器的 CPU 核數來定啟動相應數量的 Worker 程式,這樣就可以完美利用多核資源。每個程式裡都跑的是同一份原始碼,這些程式同時監聽一個埠,所以當釋出系統呼叫下線介面時,只有其中一個程式會收到請求,如果只是把收到請求的這個程式的全域性變數置為下線的話,其它的程式在收到健康檢查的時候依然返回的是線上狀態,這樣就不對了,所以要使用程式間通訊,告訴所有程式下線。
基於這些分析我們實現了 Egg.js 外掛 pp-ndp
,另外由於 Egg.js 外掛中不允許有路由,所以我們通過中介軟體的形式實現,主要程式碼如下:
const { request } = ctx;
const { path, hostname } = request;
if (path === online) {
app.messenger.sendToApp(ONLINE, '');
ctx.body = 'NDP: Nodejs Is Online';
} else if (path === offline) {
app.messenger.sendToApp(OFFLINE, '');
ctx.body = 'NDP: Nodejs Is Offline';
} else if (path === check) {
ctx.body = 'NDP: Nodejs Start Success';
} else if (path === status) {
if (app[ISONLINE]) {
ctx.body = 'NDP: Nodejs Is Online';
} else {
ctx.status = 500;
}
} else {
await next();
}
當然這個方案的前提是有多臺 Node 服務機器,並按分組進行釋出。如果只有一臺機器就沒必要這麼麻煩了,反正釋出一定會導致停服。
外掛 pp-ndp
為了滿足不同業務需求,online、offline、check、status 這四個 URL 是支援自定義配置的。
這個方案不僅解決了我們平滑釋出的問題,讓釋出不再那麼恐怖,而且還可以利用這個方案讓應用上線後能夠更好的服務,比如:可以在應用獲取配置之後再把應用置為上線狀態,或者可以在應用成功註冊或連線某服務之後再把應用置為上線狀態。讓應用保證最健康的狀態對外服務。
程式碼上 CDN 和 程式碼發現
看到 CDN 可能會奇怪, Node 應用為什麼要 CDN,其實是因為我們為了方便使用同構渲染,而把前端程式碼和 Node 程式碼放在了一個應用裡面,雖然這樣解決了服務端渲染程式碼訪問問題,但是客戶端程式碼還是走 CDN 比較合理。關於 webpack 使用 CDN 網上有很多文章可以參考,我主要介紹下如何發現前端程式碼的,包括程式碼上 CDN 和模版中插入前端程式碼 URL。
主要是使用 webpack-manifest-plugin
這個 webpack 外掛,它會生成一個檔案,比如我們用的 manifest.json
,裡面包括前端程式碼資源名稱和對應路徑,類似:
{
"vendor.js": "/static/f5e0281b/js/vendor.chunk.js",
"vendor.js.map": "/static/f5e0281b/js/vendor.chunk.js.map",
"Page.css": "/static/f2065164/css/Page.chunk.css",
"Page.js": "/static/f2065164/js/Page.chunk.js",
"Page.js.map": "/static/f2065164/js/Page.chunk.js.map",
}
只需要把這個檔案內列的檔案上傳到 CDN 即可,不需自己手動去打包目錄一個一個找。在上傳 CDN 的時候給每個檔案保持同樣路徑。使用我們實現的工具 pp-cdn
在釋出過程中的程式碼編譯完成之後進行上傳。在 Node 模版中引用程式碼時,使用我們開發的 Egg.js 外掛 pp-just
,使用方式:
```html
```
外掛內部也是讀取 manifest.json
檔案,輸出加上 CDN 域名之後的 URL,比如上面的程式碼就轉變為:
```html
```
其實之所以這麼做,是為了利用前端程式碼多版本帶來的好處,我們是使用檔案 hash 作為檔案路徑的一部分作為多版本控制的,這樣每次釋出後編譯後會把新生成的檔案路徑寫入 manifest.json
,然後通過上面講的方式就可以獲取到最新版本的程式碼。
當然目前 Node 和 前端程式碼在一起是不合理的,可能會導致不必要的釋出,後續應該會完全分離,但是使用manifest.json
也可以作為我們後續程式碼分離後的方案之一。
總結
技術方案的選擇一般要結合團隊已有的技術方案和業務需求,本文介紹的平滑釋出方案在我們業務前期,確實解決了我們的釋出問題,讓釋出變得更安全。
但是隨著業務發展我們需要灰度環境,來更好的確保應用的健康狀態,提前發現應用中的問題。另外我們還需要知道我們的應用的執行狀態,所以在下一講內容中,我們會分享關於灰度釋出和應用監控相關的內容。
相關文章
- 網易智慧企業 Node.js 實踐(3)| 灰度環境和應用監控Node.js
- 企業私有npm部署和實現npm釋出NPM
- 中央企業“智慧司庫”領先實踐
- Node.js 程式平滑離場剖析Node.js
- 通義靈碼企業程式碼補全增強使用實踐
- 前端程式碼質量-圈複雜度原理和實踐前端複雜度
- 人工智慧實踐:Tensorflow筆記:程式碼總結(2)人工智慧筆記
- 網易數帆釋出全棧低程式碼CodeWave智慧開發平臺 融合自研智慧大模型全棧大模型
- 2023中國企業敏捷實踐白皮書釋出,免費下載敏捷
- 阿里雲釋出BYOIP自帶IP上雲解決方案,助力企業平滑上雲阿里
- 通義靈碼實踐教程——企業級能力使用實踐
- 系統架構設計:平滑釋出和ABTesting架構
- 網易釋出2020年ESG報告:遊戲業務聚焦產品創新,踐行企業責任遊戲
- 前端釋出shell指令碼前端指令碼
- 前端程式碼質量的思考與實踐前端
- 網易智企釋出“易+”開源計劃,網易會議元件正式開源元件
- 釐清企業資料治理難題,《網易資料治理白皮書》重磅釋出!
- iOS 企業 ipa釋出方法iOS
- 企業BI實踐系列之二:企業定位
- 20 萬字《網易智企技術合輯》重磅釋出!
- 微信小程式實現釋出作業微信小程式
- 最佳實踐:金融級企業研發中自動和智慧SQL質量控制SQL
- 網易雲音樂低程式碼體系建設思考與實踐
- 基於Node.js的HTTP/2 Server實踐Node.jsHTTPServer
- 騰訊釋出企業微信2.0版
- J2PaaS企業級低程式碼平臺,如何支援信創企業實現國產化?
- 企業級智慧客服知識庫重磅更新,釋出`v0.1.5`
- 浪潮釋出智慧礦山解決方案,助力礦山企業智慧化建設
- jenkins配置記錄(2)--程式碼釋出流程Jenkins
- Node.js 9.0.0 釋出Node.js
- 銀彈谷:成功型企業實踐低程式碼/零程式碼平臺的一般路徑
- 高效前端程式設計實踐前端程式設計
- javascript實現網頁平滑定位程式碼例項JavaScript網頁
- 小米Kylin平滑遷移HBase實踐
- 痛入爽出 HTTP/2:程式碼實戰2HTTP
- 企業安全實踐經驗分享
- 軟通金科升級釋出"企業智慧管家(SaaS版)"平臺
- ?vue元件釋出npm最佳實踐Vue元件NPM