日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

网易智慧企业 Node.js 实践(2)| 平滑发布和前端代码

發布時間:2025/3/8 HTML 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网易智慧企业 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

<script src='{{ctx.just.use("Page.js")}}'></script>

```

?

插件內部也是讀取 `manifest.json` 文件,輸出加上 CDN 域名之后的 URL,比如上面的代碼就轉變為:

?

```html

<script src='https://qiyukf.nosdn.127.net/huke/static/f2065164/js/Page.chunk.js'></script>

```

?

其實之所以這么做,是為了利用前端代碼多版本帶來的好處,我們是使用文件 hash 作為文件路徑的一部分作為多版本控制的,這樣每次發布后編譯后會把新生成的文件路徑寫入 `manifest.json`,然后通過上面講的方式就可以獲取到最新版本的代碼。

?

當然目前 Node 和 前端代碼在一起是不合理的,可能會導致不必要的發布,后續應該會完全分離,但是使用`manifest.json`也可以作為我們后續代碼分離后的方案之一。

?

總結

?

技術方案的選擇一般要結合團隊已有的技術方案和業務需求,本文介紹的平滑發布方案在我們業務前期,確實解決了我們的發布問題,讓發布變得更安全。

?

但是隨著業務發展我們需要灰度環境,來更好的確保應用的健康狀態,提前發現應用中的問題。另外我們還需要知道我們的應用的運行狀態,所以在下一講內容中,我們會分享關于灰度發布和應用監控相關的內容。

總結

以上是生活随笔為你收集整理的网易智慧企业 Node.js 实践(2)| 平滑发布和前端代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。