Node.js(&MongoDB) 服务器崩溃,数据库操作中途?

Posted

技术标签:

【中文标题】Node.js(&MongoDB) 服务器崩溃,数据库操作中途?【英文标题】:Node.js(&MongoDB) server crashes , Database operations halfway? 【发布时间】:2013-10-28 19:37:15 【问题描述】:

我有一个带有 mongodb 后端的 node.js 应用程序将在一周内投入生产,我对如何处理应用程序崩溃和重启毫无疑问。

假设我有一个简单的路线/followUser,其中我有 2 个数据库操作

/followUser
----->Update User1 Document.followers = User2
----->Update User2 Document.followers = User1
----->Some other mongodb(via mongoose)operation

如果出现服务器崩溃(由于电源故障或远程 mongodb 服务器已关闭)会发生什么情况:

----->Update User1 Document.followers = User2
 SERVER CRASHED , FOREVER RESTARTS NODE

下面的这些操作会发生什么?系统现在处于不一致状态,每次我请求 User2 关注者时我可能都会出错

----->Update User2 Document.followers = User1
----->Some other mongodb(via mongoose)operation

还请为在 linux 中运行的应用推荐良好的日志记录和重启/监控模块。

现在我使用域来捕获异常,执行 server.close,但在 process.exit() 之前我想确保所有数据库事务都已完成,我可以通过测试事件循环是否为空来检查这一点(如何?)然后 process.exit(1) ?

【问题讨论】:

【参考方案1】:

为此您需要事务,由于 MongoDB 没有它们,这是一种解决方法http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/

【讨论】:

你对这个 TokuMX 有什么看法,它很有希望支持这种多语句交易。 我不了解 MongoDB 内部结构,但据我所知,您不能只实现 ACID 而不进行任何权衡(请参阅 en.wikipedia.org/wiki/CAP_theorem)。因此,如果您真的需要事务,最好使用带有原生事务支持的 DBMS。 ^ 这个。 MongoDB 还不支持对多个文档的完整原子操作。或者您尝试一些或多或少便宜的解决方法,或者您使用 RDBMS。【参考方案2】:

解决此问题的一种方法是将清理代码添加到应用程序启动时运行的应用程序。您编写清理代码以对数据的任何部分执行完整性检查,这些数据可以像您的示例一样通过多个步骤进行更新,然后以对您的应用程序有意义的任何方式修复该数据。

根据您的应用程序/数据的复杂性,这可能还需要您记录应用程序尝试执行的操作,但这会很快变得复杂。理想情况下,更多的是刷新非规范化数据和删除部分数据。

您希望在启动期间而不是关闭期间执行此操作,因为无法保证您的关闭代码将完全运行,如果您因异常而关闭,您不知道此时系统的状态。

【讨论】:

现在我实现了域并在 server.close() 之后调用了 mongoose.connection.close()。但是我听说如果有任何未决的 db i/o 而不是它被忽略,则不会调用 mongoose close() 。我已将 process.exit(1) 放在 mongoose 的关闭回调中。可以吗? @RanaDeep 调用mongoose.connection.close()mongoose.disconnect() 将中止任何挂起的I/O,并且应该避免调用process.exit,但在close 回调中调用它也是可以的。 ***.com/questions/8813838/… 在问题的编辑中,它说 mongoose.connection.close() 如果有任何挂起的 I/O 将被忽略,我不知道它是否已在最新版本中修复? @RanaDeep 也许曾经有一段时间它是这样工作的,但现在已经不行了。我刚刚测试过。 哦,非常感谢。但是我有问题,如果出现错误,我只想在所有 I/O 完成时调用 close(),我如何确保所有与 mongo 相关的 I/O 都完成,以便我几乎可以确定所有事务完成后安全退出。我知道这里没有什么是完全“安全”的【参考方案3】:

vkurchatkin 在this link 中给出的解决方案是一种解决方法,以防您的应用服务器崩溃,因为您将能够知道当时哪些事务处于待处理状态。如果您在代码中实现这一点,您可以按照 JohnnyHK 的建议在系统重新启动时创建清理代码。您提到的代码(捕获异常,关闭时测试等)将无法正常工作,因为...好吧..您的服务器崩溃了! ;-)

也就是说,这是使用数据库完成的,因此您必须保证您的数据库不会崩溃。我建议您为此使用replication。它基本上是一个服务器集群,如果一个节点发生故障,它会自行恢复,您也可以进行一些检查以确保数据到达服务器并且是安全的。

希望这会有所帮助。

【讨论】:

复制不能保证你的数据库不会崩溃!事实上,副本集的存在是因为它保证你的服务器迟早会崩溃! :) @Asya Kamsky - 我明白你的意思,服务器迟早会崩溃。事实上,正如您所指出的,这就是我建议使用副本集的原因。数据库服务器将崩溃,但如果您有复制活动,数据库仍然可以工作,恢复将自动完成(如果它是崩溃的主服务器,则会选择一个新的主服务器,如果它是辅助服务器,那么,没什么不好发生)。当然,我说的是不同服务器中的副本集(否则就没有意义了!)。我建议遵循 vkurchatkin 方法来处理应用服务器崩溃 plus 副本集。

以上是关于Node.js(&MongoDB) 服务器崩溃,数据库操作中途?的主要内容,如果未能解决你的问题,请参考以下文章

Node JS & MongoDB - 发布和获取 iOS 服务器 api 的图像

Node.js | MongoDB 入门讲解 & Mongoose 模块的初步应用

node.js对mongodb的连接&增删改查(附async同步流程控制)

Node js & mongoDB - TypeError: db.collection is not a function

Node.JS、Express 和 MongoDB :: 多个集合

JSONP 支持 node.js 和 mongo