javascript - 实时更新 Node.js 服务器

标签 javascript node.js express

我想设计一个实时更新的 Node.js Express 服务器,可能有一个特定的路由,比如/update,它加载一个新的配置文件。我现在唯一担心的是,更新发生时服务器可能处于任何状态。如果我在正在处理用户请求的 JS 消息时加载新的配置文件,则在用户请求开始时可能有一个配置,在请求完成之前加载新配置文件时可能有第二个配置。我能想到的防止这种情况的唯一方法是关闭服务器至少一分钟(保持服务器运行,但完全阻止任何传入请求),然后更新服务器并将其重新上线,但这并不是真正的情况热重载或实时更新的最佳形式是什么呢?

如何以某种方式欺骗 JS 事件循环,以便仅在所有请求完成后才加载配置文件,并将任何新请求延迟到配置加载之后?

一种算法是:

  1. 设置一个标志“开始重新配置”
  2. 上述标志会阻止处理任何新请求(使用 Express 中间件)
  3. 检查当前所有请求是否已完成(这里想不出比轮询循环更好的方法了)
  4. 完成上述检查后,加载新配置
  5. 加载配置后,将标志从 (1) 切换

最佳答案

Disclaimer: I have not tried this in production. In fact, I have not tried this at all. while I believe the idea is sane, there may be hidden pitfalls along the road which are not currently known to me.

许多 Node.js 开发人员往往会忘记/没有完全意识到一件事:

一次只能执行一个 JavaScript 语句。

您可以稍后执行异步 I/O 或执行函数,这并不重要。无论你如何努力,你编写的所有 JS 代码都是在单线程中执行的,没有并行性。只有底层实现(完全不受我们控制)可以并行执行操作。

这对我们很有帮助,因为只要我们的更新过程是同步的,就不能执行其他 JS 代码(即客户端响应)。

配置实时修补

防止请求中配置更改的解决方案相当简单:

每个请求都会获取自己的应用程序配置副本。

如果应用程序的配置位于 JavaScript 对象中,则只需为每个新请求克隆该对象即可。这意味着即使您突然更改配置,它也只会应用于新的传入请求。

There are tons of modules for cloning (even deep cloning) objects, but since I believe mine is best I will use this opportunity for some small self-promotion - semantic-merge.

代码实时修补

这有点棘手,但通常只要付出足够的努力就可以实现。

这里的技巧是首先 remove/unregister current Express routes ,清除Node's require cache ,再次需要更新的文件并重新注册路由处理程序。现在,Express 将使用旧代码完成所有挂起的请求(这是因为只要代码包含事件对象引用,Node 就无法从内存中删除这些旧函数 - 它会这样做 - reqres )并使用新需要的模块/路由来处理新的传入请求。一旦不再有以旧代码开始的请求,旧代码应该立即从内存中释放。

在请求处理期间,您不得在任何地方使用 require,否则您将面临与在请求中更改配置相同的问题。您当然可以在模块级作用域中使用 require ,因为它将在需要模块本身时执行,从而是同步的。

示例:

// app/routes/users.js (or something)

// This is okay, because it is executed only once - when users.js
// itself is required
var path = require('path')

// This function is something you would put into app.use()
module.exports = function usersRoute (req, res, next) {
  // Do not use require() here! It will be executed per-request!
}

关于javascript - 实时更新 Node.js 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30786875/

相关文章:

javascript - 需要帮助从 Firebase 检索数据

javascript - 尝试在 javascript 中捕获错误 - 获取更多错误详细信息

javascript - Node JS 创建从图片到数据库的链接

node.js - TypeError : crypto. createHmac 不是函数

node.js - 耐克斯 :Error Pool2 - Error: connect ECONNREFUSED

javascript - express - winston : Write Express Access Logs to File

javascript - 如何使一个选择框的值驱动第二个选择框的选项

javascript - 粘性导航和 jQuery

javascript - 将 Promise 包装在解决 Promise 的对象中有哪些缺点?

jquery - 允许 CORS REST 请求到 express/node.js 应用程序