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

Why do we need connection pool in node.js when node is single threaded?

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

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

作为一名开发人员,我创建了 1 个 redis 或 mysql 连接并将其重新用于 send/get 数据。当数据到达时,节点将调用回调来处理数据。

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

我的问题是:当节点是单线程时,为什么我们在 node.js 中需要连接池?有什么好处吗? Node 是否不会在开发人员无需这样做的情况下利用底层 OS 和 javascript 引擎的多线程功能?

谢谢

Node 运行s your 代码单线程。但是,Node.js 实际上有一个您的代码无法访问的线程池供其使用。线程机制是通过 libuv. Take a look at libuv book 深入实施的,并解释了 libuv 的内部工作原理。

基本上,您的代码是 运行 在事件循环(单线程)的上下文中。然后,所有异步工作都从池中卸载到可用线程,事件循环将只进行轮询,直到其中一个线程完成该异步工作。完成后,异步调用注册的回调函数将被调用,并将在事件循环的下一个 I/O Callback Phase 期间继续处理。您可以在 Node.js docs.

中阅读有关事件循环及其阶段的更多信息

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

您需要连接池,因为即使是单个线程也可以容纳多个 "blocking" 数据库连接(这里假设是 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 完成。就在这个单线程中,我们已经使用了三个资源来连接到数据库。想象一下,每次需要数据库操作时都必须创建每一个。只从连接池中抓取一个就快多了!