我想了解与基于线程的方法(如Servlet服务器)相比,nodejs如何实现更高的并发性。NodeJS如何处理高并发请求?
我已经知道在nodejs中“除了你的代码以外所有东西都是并行运行的”,并且在libuv中还有一个后端线程池来处理通常是瓶颈的文件IO或数据库调用。
所以,这里是我的问题:如果nodejs使用线程池来处理数据库调用,那么它如何能够服务更高的并发请求,比Tomcat等Servlet服务器更好,因为Tomcat也可以使用由epoll/kqueue支持的NIO来实现高并发性?例如,如果有100k个并发请求进入并且每个请求都需要数据库操作,如果这些100k请求需要同时服务,那么使用nodejs,我们最终还是会创建100k个线程,这可能会导致内存耗尽,正如Tomcat所做的那样。是的,100k线程只是一个想象,因为(我知道)nodejs有一个固定的线程池,不同的操作在事件循环中排队,但是使用Tomcat它以相同的方式处理事情 - 我们也可以配置线程池在Tomcat中的大小,它也排队请求。
或者,我错了,说“nodejs使用libuv中的后端线程池来处理文件IO或数据库调用”? nodejs是否使用epoll/kqueue来处理数据库io而没有单独的线程?
我在读this similar question,但仍然没有得到答案。
感谢您的全面解释。当我谈到数据库调用时,主要是指来自客户端的调用,在这种情况下,我们的js代码充当数据库客户端。是的,数据库调用最终是网络套接字io,所以我可以说,在数据库调用来自客户端的数据库调用覆盖的底层io机制,如epoll/kqueue包装libuv?否则我无法想象在数据库调用异步时没有使用线程的场景。 – davenkin
@davenkin - 您的数据库评论令我困惑。通常,运行数据库的实际代码将与node.js(有时在另一个主机上)处于不同的进程中。当node.js中的Javascript向客户端调用数据库时,它将准备与其他进程或其他主机的某些通信。该通信通常不会使用node.js线程,因为它通常是非阻塞TCP并且node.js不会为每个TCP连接使用额外的线程。 – jfriend00
@davenkin - 给你一个想法。如果我编写node.js应用程序来向100个不同的主机发起http API调用,以便所有100个请求同时处于运行状态并等待响应,但不会在node.js中使用任何其他线程。现在,如果node.js中的数据库驱动程序具有自己的本机代码,那么它可以在其自己的本机代码中执行任何它想要的操作。有些人可能会使用一些本地线程来跟踪请求 - 我不知道。但是,根本不需要node.js模型。 – jfriend00