久久久久在线观看_又色又爽又黄的免费视频播放_一区中文字幕_日韩电影在线播放

今日頭條 焦點資訊 營銷之道 企業報道 淘寶運營 網站建設 軟件開發 400電話
  當前位置: 首頁 » 資訊 » 網站建設 » 正文

Node.js Web應用代碼熱更新的另類思路

放大字體  縮小字體 發布日期:2018-02-18  來源:新格網  作者:新格網  瀏覽次數:890  【去百度看看】
核心提示:本文則提供了另外一種思路,只需要很小的改造,就可以實現真正的0重啟熱更新代碼,解決 Node.js 開發 Web 應用時惱人的代碼更新問題。

背景

相信使用 Node.js 開發過 Web 應用的同學一定苦惱過新修改的代碼必須要重啟 Node.js 進程后才能更新的問題。習慣使用 PHP 開發的同學更會非常的不適用,大呼果然還是我大PHP才是世界上最好的編程語言。手動重啟進程不僅僅是非常惱人的重復勞動,當應用規模稍大以后,啟動時間也逐漸開始不容忽視。

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

本文則提供了另外一種思路,只需要很小的改造,就可以實現真正的0重啟熱更新代碼,解決 Node.js 開發 Web 應用時惱人的代碼更新問題。

總體思路

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

由于我也沒有使用過 Erlang ,以下內容均為道聽途說,如果希望深入和準確的了解 Erlang 的代碼熱更新實現,最好還是查閱官方文檔。

  • Erlang 的代碼加載由一個名為code_server的模塊管理,除了啟動時的一些必要代碼外,大部分的代碼均是由code_server加載。
  • code_server發現模塊代碼被更新后,會重新加載模塊,此后的新請求會使用新模塊執行,而原有還在執行的請求則繼續使用老模塊執行。
  • 老模塊會在新模塊加載后,被打上old標簽,新模塊則是current標簽。當下一次熱更新的時候,Erlang 會掃描還在執行老模塊的進行并殺掉,再繼續按照這個邏輯更新模塊。
  • Erlang 中并非所有代碼均允許熱更新,如 kernel, stdlib, compiler 等基礎模塊默認是不允許更新的

我們可以發現 Node.js 中也有與code_server類似的模塊,即 require 體系,因此 Erlang 的做法應該也可以在 Node.js 上做一些嘗試。通過了解 Erlang 的做法,我們可以大概的總結出在 Node.js 中解決代碼熱更新的關鍵問題點

  • 如何更新模塊代碼
  • 如何使用新模塊處理請求
  • 如何釋放老模塊的資源

那么接下來我們就逐個的解析這些問題點。

如何更新模塊代碼

要解決模塊代碼更新的問題,我們就需要去閱讀 Node.js 的模塊管理器實現,直接上鏈接 module.js。通過簡單的閱讀,我們可以發現核心的代碼就在于 Module._load ,稍微精簡一下代碼貼出來。

// 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;

可以發現其中的核心就是 Module._cache ,只要清除了這個模塊緩存,下一次 require 的時候,模塊管理器就會重新加載最新的代碼了。

寫一個小程序驗證一下:

// 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';

我們執行一下 main.js ,同時取修改 code.js 的內容,就可以發現控制臺中,我們代碼成功的更新為了最新的代碼。

那么模塊管理器更新代碼的問題已經解決了,接下來再看看在 Web 應用中,我們如何讓新的模塊可以被實際執行。

 
 
[ 資訊搜索 ]  [ 加入收藏 ]  [ 告訴好友 ]  [ 打印本文 ]  [ 違規舉報 ]  [ 關閉窗口 ]

 
0條 [查看全部]  相關評論

 
網站首頁 | 關于我們 | 聯系方式 | 使用協議 | 版權隱私 | 網站地圖 | 排名推廣 | 廣告服務 | 積分換禮 | 網站留言 | RSS訂閱 | 吉ICP備11001726號-6
企業800網 · 提供技術支持