当节点是单线程时,为什么我们需要node.js中的连接池?

时间:2017-07-07 15:12:04

标签: node.js redis pooling

Node.js是单线程的。 Javascript V8引擎和一些内部库是多线程的。对于I / O,节点将I / O委托给可能是多线程的OS。

如果我的node.js应用程序连接到redis或sql / mariadb服务器,我认为我不需要redis或mysql的连接池。

作为开发人员,我创建了1个redis或mysql连接并重用它来发送/获取数据。当数据到达时,节点将调用回调来处理数据。

我理解与Java / .NET的连接池,但它们是多线程的,因此Java / .NET中的连接池有明显的好处。

我的问题是:当节点是单线程时,为什么我们需要node.js中的连接池?它有什么好处吗?如果没有开发人员必须这样做,节点是否会利用底层操作系统和javascript引擎的多线程功能?

由于

2 个答案:

答案 0 :(得分:3)

节点运行 您的 代码单线程。但是,Node.js实际上有一个代码无法访问的线程池。线程机制使用libuv实现。深入了解libuv book,并解释libuv的内部工作原理。

基本上,您的代码在Event Loop(单线程)的上下文中运行。然后将任何异步工作从池中卸载到可用线程,并且事件循环将仅轮询,直到其中一个线程完成异步工作。完成后,将调用异步调用注册的回调函数,并在事件循环的下一个I/O Callback Phase期间进行处理。您可以在Node.js docs中了解有关事件循环及其阶段的更多信息。

使用此事件循环样式构建应用程序的一个好处是,通常与多线程应用程序相关联的关键部分编码(互斥体,信号量等)的抽象。

答案 1 :(得分:1)

您需要连接池,因为即使是单个线程也可以容纳多个“阻塞”数据库连接(假设此处为RDBMS)。如果没有连接池,您的应用程序将为每个额外的数据库请求从头开始创建每个连接,即使在像Node这样的异步/非阻塞系统中也是如此。

示例:

request 1 - insert user  -- wait for response (assume it's 5 secs)
request 2 - insert invoice - wait for response (assume it's 3 secs)
request 3 - insert another invoice

请注意,会立即处理请求3 ,而无需等待请求1和2完成。就在这个单线程中,我们已经使用了三个资源来连接数据库。想象一下,每次需要DB操作时都必须创建每个。从连接池中获取一个会快得多!