我的 app.js 中包含以下代码,该代码在服务器启动(npm启动)上运行
mongo.mongoConnect('connection_string', 'users').then((x) => {
console.log('Database connection successful');
app.listen(5000, () => console.log('Server started on port 5000'));
})
.catch(err => {
console.error(err.stack);
process.exit(1);
});
process.on('SIGINT', mongo.mongoDisconnect).on('SIGTERM', mongo.mongoDisconnect);
如您所见,我打开了SIGINT和SIGTERM来关闭 process.exit
上的连接我已经阅读了很多有关如何在mongo中处理数据库连接的知识,并且知道我应该只调用一次它并在整个应用程序中使用它。
这是否意味着即使在将数据保存到mongo中并随后进行POST请求时,即使在执行save()方法之后,我也不应该关闭连接?如果我将其关闭,由于连接是在应用启动时发生的,我该如何再次调用它?
我问这个问题是因为在PHP中,我习惯于在查询MySql数据库后始终打开和关闭我的连接。
同样,这是否意味着该连接仅在服务器关闭时才会关闭,换句话说,由于我不想关闭我的node.js后端实例,该连接将一直存在?
答案 0 :(得分:3)
打开连接,运行查询然后关闭连接在形式上是正确的,但这不是一个好习惯,因为打开连接是一项“昂贵的”操作,并且连接可以重用,这要更多高效。开放连接的主要限制是一次只能由1个线程使用。 (更准确地说,一旦在连接上发送了请求,在接收到对该请求的响应之前,就无法在该连接上发送其他请求。)
如果您的应用程序寿命短或本质上是单线程的(例如作为“无服务器”功能运行时的情况),则可以在每个请求上打开和关闭连接。
从理论上讲,可以在程序启动时打开单个连接,保留对该连接的全局引用,然后重新使用它,但实际上,存在一些使连接变得不可用的常见方法要考虑和处理所有可能性需要复杂的代码。当与MongoDB副本集(可能)实际连接到多个服务器并想在第二台服务器上重试命令(如果第一个服务器无法响应)时,情况变得更加复杂。
这就是为什么标准和“最佳”做法是使用“连接池”来管理数据库连接的原因。池将打开与数据库的一组网络连接,验证并维护其运行状况,并根据需要将虚拟数据库连接动态分配给实际的网络连接。该池在一个已实现大量实际测试的库中实现,并且极有可能比您自己编写的任何内容都要好。连接池具有配置选项,可让您设置所需的行为,包括为每个请求打开一个新连接并在完成后关闭它,但提供了广泛的性能增强功能,例如重用连接并避免了创建它们的开销对于每个请求。
这就是为什么对于MongoDB,standard Node.js client已经实现了连接池的原因。我不知道您的代码中的mongo.mongoConnect
是指什么;您在标题中说您正在使用mongoose
,但它使用connect
,而不是mongoConnect
连接数据库。通常,您应该使用标准客户端或JavaScript ORM库,例如mongoose
。他们中的任何一个都会为您解决连接管理问题。
请参阅所使用的客户端/库的文档,以获取正确的使用方法。通常,在进入主应用程序处理程序之前,您将初始化某种客户端对象并将其全局存储。然后,您将使用该对象来处理数据库操作,并且该对象将通过池实现透明地管理基础连接。在这种设置中,只有在退出程序时才关闭连接,通常库会自动为您处理,因此您实际上不需要关闭连接。
因此,在NodeJS中使用MongoDB连接池时,您编写程序的方式基本上与启动时打开连接然后继续重用它的方式相同。这些库负责将您与实际执行此操作可能引起的所有问题隔离开来。使用标准MongoDB NodeJS库时,您不需要,实际上也不需要在数据库操作后关闭连接。
请注意,存在其他确实需要您关闭连接的连接池实现。您对这些池所做的工作是保留(或“签出”或“打开”)连接,将其用于多个操作,并在完成后释放连接(或“签入”或“关闭”)连接。这可能就是您在PHP中所做的。请务必阅读并遵循所使用连接池库的文档,以确保正确使用它。
答案 1 :(得分:2)
这可能不是您要查找的确切答案,但是对于每个请求都打开一个新连接然后关闭它不是一个好主意。这是一项开销,因为创建新连接需要花费一些时间(甚至以毫秒为单位)。
相反,您应该创建一个连接池并在您的应用程序中使用它。
答案 2 :(得分:1)
在进程终止或停止时关闭mongo连接是一个好主意,但每次成功查询后,您都不需要关闭mongoose连接。
如果您要在每个查询之前实例化一个新的mongo连接,则也不需要这样做。您只需在启动服务器时执行一次。
答案 3 :(得分:0)
您有两种方法 1)使用中间件在每个呼叫上重新打开连接 2)您必须稍后将其查询保存到节点中,一次执行一次