Node.js单线程机制
Node.js single-thread mechanism
我了解到 Node.js 是单线程和非阻塞的。在这里我看到了很好的解释
但是第一个答案说
The seemingly mysterious thing is how both the approaches above manage to run workload in "parallel"? The answer is that the database is threaded. So our single-threaded app is actually leveraging the multi-threaded behaviour of another process: the database.
(1) 这让我很困惑。以一个简单的快递应用为例,当我
var monk = require('monk');
var db = monk('localhost:27017/databaseName');
router.get('/QueryVideo', function(req, res) {
var collection = db.get('videos');
collection.find({}, function(err, videos){
if (err) throw err;
res.render('index', { videos: videos })
});
});
并且当我的路由器通过执行简单的 MongoDB 查询来响应多个请求时。这些查询是否由不同的线程处理?我知道节点中只有一个线程到路由器客户端请求。
(2) 我的第二个问题是,这样的单线程节点应用如何保证安全?我不太了解安全性,但看起来应该隔离多请求(至少不同的内存space?)即使多线程应用程序不能确保安全性,因为它们仍然共享很多东西。我知道这可能不是一个合理的问题,但在今天的云服务中,隔离似乎是一个重要的话题。我迷失在使用 Node.js 环境的无服务器、wasm 和基于 wasm 的无服务器等主题中。
感谢您的帮助!!
(1) 大局是这样的;对于 nodejs 有两种类型的线程:事件(单)和工人(池)。只要你不阻塞事件循环,在 nodejs 将阻塞的 I/O 调用放置到工作线程之后; nodejs 继续为下一个请求提供服务。工作人员会将完成的 I/O 放回事件循环以进行下一步操作。
简而言之,主线程:“需要等待时做其他事情,等待结束时返回并继续,一次做一个”。
而且这种反应机制与另一个进程(即数据库)中的线程运行ning无关。数据库可能部署其他类型的线程管理方案。
(2) 你问题中的'memory space'在同一个进程space。一个线程属于一个进程(即 Express 应用程序 A),从不 运行 在其他进程(即 Fastify 应用程序 B)中 space.
既然你问了我的回答,我想我可以帮忙澄清一下。
1
对于处理触发多个并行 MongoDB 查询的多个并行客户端请求的特定情况,您询问:
Are those queries handled by different threads?
在 node.js 上,因为 MongoDB 通过网络堆栈 (tcp/ip) 连接,所有并行请求都在单个线程中处理。 魔法 是一个系统API,它允许您的程序并行等待。 Node.js 使用 libuv 到 select 使用哪个 API 取决于编译时使用哪个 OS。但是哪个 API 并不重要。知道所有现代 OSes 都有 APIs 允许您并行等待多个套接字(而不是通常在多个 threads/processes 中等待单个套接字)就足够了。这些API统称为异步I/OAPI.
关于MongoDB.. 我对MongoDB了解不多。 Mongo 可以在多线程中实现,也可以像 node.js 一样是单线程的。磁盘 I/O 本身由 OS 并行处理而不使用线程,而是使用 I/O 通道(例如 PCI lanes) and DMA 通道。基本上 threads/processes 和异步 I/O 通常由 OS(至少在 Linux 和 Mac 上)使用相同的底层系统实现:OS 事件。和 OS 事件只是处理中断的函数。无论如何,这与关于数据库的讨论相去甚远..
我知道 MySQL 和 Postgresql 都是多线程处理解析 SQL 查询循环(SQL 中的查询处理基本上是循环遍历行的操作并过滤结果 - 这需要 I/O 和 CPU 这就是它们是多线程的原因)
如果您仍然好奇计算机如何在没有 CPU 执行单个指令的情况下执行操作(例如等待 I/O),您可以查看我对以下相关问题的回答:
2
安全性由被解释的语言确保,并确保解释器没有任何堆栈溢出或下溢错误。在大多数情况下,所有现代 javascript 引擎都是如此。通过程序输入注入代码和执行外部代码的主要机制是通过缓冲区溢出或下溢。能够执行外部代码然后允许您访问内存。如果您不能执行外部代码,那么能够访问内存就没有实际意义了。
在某些编程语言文化中,还有第二种注入外部代码的机制:code eval(我在看着你 PHP!)。使用字符串替换以任何语言构造数据库查询都会使您面临 sql 代码评估攻击(通常称为 sql 注入),而不管您的程序的内存模型如何。 Javascript 本身有一个 eval()
功能。为了防止这种 javascript 程序员简单地考虑 eval
邪恶。基本上,针对 eval
的保护取决于良好的编程实践,并且 Node.js 开源允许任何人查看代码并报告任何可能发生代码评估攻击的情况。从历史上看,Node.js 在这方面一直做得很好 - 所以您对代码评估的安全性的主要保证是 Node 的声誉。
我了解到 Node.js 是单线程和非阻塞的。在这里我看到了很好的解释
The seemingly mysterious thing is how both the approaches above manage to run workload in "parallel"? The answer is that the database is threaded. So our single-threaded app is actually leveraging the multi-threaded behaviour of another process: the database.
(1) 这让我很困惑。以一个简单的快递应用为例,当我
var monk = require('monk');
var db = monk('localhost:27017/databaseName');
router.get('/QueryVideo', function(req, res) {
var collection = db.get('videos');
collection.find({}, function(err, videos){
if (err) throw err;
res.render('index', { videos: videos })
});
});
并且当我的路由器通过执行简单的 MongoDB 查询来响应多个请求时。这些查询是否由不同的线程处理?我知道节点中只有一个线程到路由器客户端请求。
(2) 我的第二个问题是,这样的单线程节点应用如何保证安全?我不太了解安全性,但看起来应该隔离多请求(至少不同的内存space?)即使多线程应用程序不能确保安全性,因为它们仍然共享很多东西。我知道这可能不是一个合理的问题,但在今天的云服务中,隔离似乎是一个重要的话题。我迷失在使用 Node.js 环境的无服务器、wasm 和基于 wasm 的无服务器等主题中。
感谢您的帮助!!
(1) 大局是这样的;对于 nodejs 有两种类型的线程:事件(单)和工人(池)。只要你不阻塞事件循环,在 nodejs 将阻塞的 I/O 调用放置到工作线程之后; nodejs 继续为下一个请求提供服务。工作人员会将完成的 I/O 放回事件循环以进行下一步操作。
简而言之,主线程:“需要等待时做其他事情,等待结束时返回并继续,一次做一个”。
而且这种反应机制与另一个进程(即数据库)中的线程运行ning无关。数据库可能部署其他类型的线程管理方案。
(2) 你问题中的'memory space'在同一个进程space。一个线程属于一个进程(即 Express 应用程序 A),从不 运行 在其他进程(即 Fastify 应用程序 B)中 space.
既然你问了我的回答,我想我可以帮忙澄清一下。
1
对于处理触发多个并行 MongoDB 查询的多个并行客户端请求的特定情况,您询问:
Are those queries handled by different threads?
在 node.js 上,因为 MongoDB 通过网络堆栈 (tcp/ip) 连接,所有并行请求都在单个线程中处理。 魔法 是一个系统API,它允许您的程序并行等待。 Node.js 使用 libuv 到 select 使用哪个 API 取决于编译时使用哪个 OS。但是哪个 API 并不重要。知道所有现代 OSes 都有 APIs 允许您并行等待多个套接字(而不是通常在多个 threads/processes 中等待单个套接字)就足够了。这些API统称为异步I/OAPI.
关于MongoDB.. 我对MongoDB了解不多。 Mongo 可以在多线程中实现,也可以像 node.js 一样是单线程的。磁盘 I/O 本身由 OS 并行处理而不使用线程,而是使用 I/O 通道(例如 PCI lanes) and DMA 通道。基本上 threads/processes 和异步 I/O 通常由 OS(至少在 Linux 和 Mac 上)使用相同的底层系统实现:OS 事件。和 OS 事件只是处理中断的函数。无论如何,这与关于数据库的讨论相去甚远..
我知道 MySQL 和 Postgresql 都是多线程处理解析 SQL 查询循环(SQL 中的查询处理基本上是循环遍历行的操作并过滤结果 - 这需要 I/O 和 CPU 这就是它们是多线程的原因)
如果您仍然好奇计算机如何在没有 CPU 执行单个指令的情况下执行操作(例如等待 I/O),您可以查看我对以下相关问题的回答:
2
安全性由被解释的语言确保,并确保解释器没有任何堆栈溢出或下溢错误。在大多数情况下,所有现代 javascript 引擎都是如此。通过程序输入注入代码和执行外部代码的主要机制是通过缓冲区溢出或下溢。能够执行外部代码然后允许您访问内存。如果您不能执行外部代码,那么能够访问内存就没有实际意义了。
在某些编程语言文化中,还有第二种注入外部代码的机制:code eval(我在看着你 PHP!)。使用字符串替换以任何语言构造数据库查询都会使您面临 sql 代码评估攻击(通常称为 sql 注入),而不管您的程序的内存模型如何。 Javascript 本身有一个 eval()
功能。为了防止这种 javascript 程序员简单地考虑 eval
邪恶。基本上,针对 eval
的保护取决于良好的编程实践,并且 Node.js 开源允许任何人查看代码并报告任何可能发生代码评估攻击的情况。从历史上看,Node.js 在这方面一直做得很好 - 所以您对代码评估的安全性的主要保证是 Node 的声誉。