2017-07-07 75 views
0

Node.js是单线程的。 Javascript V8引擎和一些内部库是多线程的。对于I/O,节点将I/O委托给可能是多线程的OS。节点为单线程时,为什么我们需要node.js中的连接池?

如果我的Node.js应用程序连接到Redis的,或者SQL/MariaDB的服务器,我想我不应该需要的Redis或MySQL连接池。

作为开发人员,我创造1个Redis的或MySQL连接并复用它来发送/获取数据。当数据到达时,节点将调用回调来处理数据。

我明白连接与Java/.NET池,但他们是多线程的,所以用Java/.NET连接池有明显的好处。

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

感谢

回答

2

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

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

之一建立与该事件循环样式的应用程序的好处,是通常与多线程应用程序相关联的临界区编码(mutexs,信号量等)的抽象。

+0

谢谢你的评论和链接。那么使用redis连接池或mysql连接池会有什么好处,因为节点将使用其内部线程池进行I/O操作? – Avneet

+0

当然,这些连接池仍然让你有正在为等待新的连接被打开头顶的共享和可代替多个连接。这是正确实施时的优化。 – peteb

+0

@Avneet也从Redis的和mysql的线程池,仍在与libuv就像你的代码运行。所以没有一个由这些软件包创建的独立池。你的代码是用这些包实现的,你的代码是单线程运行的,这些池只是提供开放的连接,只是等待工作。无需等待连接打开。 – peteb

0

您需要连接池,因为即使一个线程可以拥有多个“堵” DB连接(假设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操作时都必须创建每一个。从连接池中获取一个更快!