为什么不可能发送更多的消息(string)分叉子stream程?
问题
为什么不可能在NodeJS中发送更多的消息(string)给分叉的subprocess呢? 这个答案只是说,这是不可能的,但没有提供任何解释。
这个问题是如何产生的
我需要发送数据库连接到subprocess,以避免连接到这些数据库多次。
我的程序连接到四个不同的服务: Redis , OrientDB , Postgres和ElasticSearch 。
我正在做一些繁重的工作,并且需要使用多个进程,并让所有进程连接到这些服务。 我已经做了一个对象,以容纳所有这些客户:
var clients = { redisClient: /* redis connection */ orientClient: /* orientdb connection */ pgClient: /* postgres connection */ elasticClient: /* elasticsearch connection */ };
但是,当我将客户端发送到subprocess:
var child = cp.fork(__dirname + '/singleCrawler.js'); child.send(clients);
我得到以下错误:
TypeError: Converting circular structure to JSON at Object.stringify (native) at ChildProcess.target.send (child_process.js:451:23)
我不是唯一有这个问题的人。
我的问题的解决scheme
我要产生处理服务的另一个进程。 其他进程将与此进程进行通信以与服务进行交互。
之所以不能将任意的javascript对象传递给subprocess,是因为它运行的是一个完全独立的V8进程,它不会与父进程共享任何内存。
在你的情况下,我会为每个进程打开一组单独的连接。 既然你不会有数百个节点进程,这对你的dbs来说不会是一个很大的负担,它会使你的代码更简单。
(无关)
实际上有一个例外,你可以传递给另一个进程:你可以传递一个文件描述符 :
child.send(消息,[sendHandle])
child.send()的sendHandle选项用于将TCP服务器或套接字对象发送到另一个进程。 孩子将接收该对象作为消息事件的第二个参数。
这由集群模块使用。 这在你的情况下不是很有用,但我想我会提到的:)
为什么不可能的原因之一是因为它不是微不足道的:如果你有一个连接到多个进程之间共享的Redis,将如何处理并发读写?
至less在Unixtypes的操作系统上,你可以在进程之间传递文件描述符,但这并不能解决并发问题。 这也是非常低级的,每个节点驱动程序(Redis,OrientDB,Postgres,ElasticSearch)都不得不支持被传递的文件句柄(他们不这样做,我不知道是否有可能)。
一个进程pipe理所有数据库连接的解决scheme是一个很好的解决scheme,但我想知道为什么一些额外的数据库连接是一个如此大的问题。