Node.jsWeb應(yīng)用代碼熱更新的另類思路

背景

創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、雁峰網(wǎng)絡(luò)推廣、微信小程序、雁峰網(wǎng)絡(luò)營(yíng)銷、雁峰企業(yè)策劃、雁峰品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們大的嘉獎(jiǎng);創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供雁峰建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:muchs.cn

相信使用 Node.js 開(kāi)發(fā)過(guò) Web 應(yīng)用的同學(xué)一定苦惱過(guò)新修改的代碼必須要重啟 Node.js 進(jìn)程后才能更新的問(wèn)題。習(xí)慣使用 PHP 開(kāi)發(fā)的同學(xué)更會(huì)非常的不適用,大呼果然還是我大PHP才是世界上最好的編程語(yǔ)言。手動(dòng)重啟進(jìn)程不僅僅是非常惱人的重復(fù)勞動(dòng),當(dāng)應(yīng)用規(guī)模稍大以后,啟動(dòng)時(shí)間也逐漸開(kāi)始不容忽視。

當(dāng)然作為程序猿,無(wú)論使用哪種語(yǔ)言,都不會(huì)讓這樣的事情折磨自己。解決這類問(wèn)題最直接和普適的手段就是監(jiān)聽(tīng)文件修改并重啟進(jìn)程。這個(gè)方法也已經(jīng)有很多成熟的解決方案提供了,比如已經(jīng)被棄坑的 node-supervisor,以及現(xiàn)在比較火的 PM2 ,或者比較輕量級(jí)的 node-dev 等等均是這樣的思路。

本文則提供了另外一種思路,只需要很小的改造,就可以實(shí)現(xiàn)真正的0重啟熱更新代碼,解決 Node.js 開(kāi)發(fā) Web 應(yīng)用時(shí)惱人的代碼更新問(wèn)題。

總體思路

說(shuō)起代碼熱更新,當(dāng)下最有名的當(dāng)屬 Erlang 語(yǔ)言的熱更新功能,這門語(yǔ)言的特色在于高并發(fā)和分布式編程,主要的應(yīng)用場(chǎng)景則是類似證券交易、游戲服務(wù)端等領(lǐng)域。這些場(chǎng)景都或多或少要求服務(wù)擁有在運(yùn)行中運(yùn)維的手段,而代碼熱更新就是其中非常重要的一環(huán),因此我們可以先簡(jiǎn)單的了解一下 Erlang 的做法。

由于我也沒(méi)有使用過(guò) Erlang ,以下內(nèi)容均為道聽(tīng)途說(shuō),如果希望深入和準(zhǔn)確的了解 Erlang 的代碼熱更新實(shí)現(xiàn),最好還是查閱官方文檔。

Erlang 的代碼加載由一個(gè)名為code_server的模塊管理,除了啟動(dòng)時(shí)的一些必要代碼外,大部分的代碼均是由code_server加載。 當(dāng)code_server發(fā)現(xiàn)模塊代碼被更新后,會(huì)重新加載模塊,此后的新請(qǐng)求會(huì)使用新模塊執(zhí)行,而原有還在執(zhí)行的請(qǐng)求則繼續(xù)使用老模塊執(zhí)行。 老模塊會(huì)在新模塊加載后,被打上old標(biāo)簽,新模塊則是current標(biāo)簽。當(dāng)下一次熱更新的時(shí)候,Erlang 會(huì)掃描還在執(zhí)行老模塊的進(jìn)行并殺掉,再繼續(xù)按照這個(gè)邏輯更新模塊。 Erlang 中并非所有代碼均允許熱更新,如 kernel, stdlib, compiler 等基礎(chǔ)模塊默認(rèn)是不允許更新的

我們可以發(fā)現(xiàn) Node.js 中也有與code_server類似的模塊,即 require 體系,因此 Erlang 的做法應(yīng)該也可以在 Node.js 上做一些嘗試。通過(guò)了解 Erlang 的做法,我們可以大概的總結(jié)出在 Node.js 中解決代碼熱更新的關(guān)鍵問(wèn)題點(diǎn)

如何更新模塊代碼 如何使用新模塊處理請(qǐng)求 如何釋放老模塊的資源

那么接下來(lái)我們就逐個(gè)的解析這些問(wèn)題點(diǎn)。

如何更新模塊代碼

要解決模塊代碼更新的問(wèn)題,我們就需要去閱讀 Node.js 的模塊管理器實(shí)現(xiàn),直接上鏈接 module.js。通過(guò)簡(jiǎn)單的閱讀,我們可以發(fā)現(xiàn)核心的代碼就在于 Module._load ,稍微精簡(jiǎn)一下代碼貼出來(lái)。

// Check the cache for the requested file.
// 1. If a module already exists in the cache: return its exports object.
// 2. If the module is native: call `NativeModule.require()` with the
// filename and return the result.
// 3. Otherwise, create a new module for the file and save it to the cache.
// Then have it load the file contents before returning its exports
// object.
Module._load = function(request, parent, isMain) {
var filename = Module._resolveFilename(request, parent);

var cachedModule = Module._cache[filename];
if (cachedModule) {
return cachedModule.exports;
}

var module = new Module(filename, parent);
Module._cache[filename] = module;
module.load(filename);

return module.exports;
};

require.cache = Module._cache;

可以發(fā)現(xiàn)其中的核心就是 Module._cache ,只要清除了這個(gè)模塊緩存,下一次 require 的時(shí)候,模塊管理器就會(huì)重新加載最新的代碼了。

寫一個(gè)小程序驗(yàn)證一下:

// main.js
function cleanCache (module) {
var path = require.resolve(module);
require.cache[path] = null;
}

setInterval(function () {
cleanCache(\'./code.js\');
var code = require(\'./code.js\');
console.log(code);
}, 5000);

// code.js
module.exports = \'hello world\';

我們執(zhí)行一下 main.js ,同時(shí)取修改 code.js 的內(nèi)容,就可以發(fā)現(xiàn)控制臺(tái)中,我們代碼成功的更新為了最新的代碼。

那么模塊管理器更新代碼的問(wèn)題已經(jīng)解決了,接下來(lái)再看看在 Web 應(yīng)用中,我們?nèi)绾巫屝碌哪K可以被實(shí)際執(zhí)行。

分享標(biāo)題:Node.jsWeb應(yīng)用代碼熱更新的另類思路
網(wǎng)站路徑:http://muchs.cn/article38/cheipp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、微信小程序ChatGPT、虛擬主機(jī)靜態(tài)網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司