为什么不能将多个消息(字符串)发送到分叉子进程?

时间:2013-11-10 21:07:36

标签: node.js process

问题

为什么不能将更多消息(字符串)发送到NodeJS中的分叉子进程? This answer只是表明这是不可能的,但不提供任何解释。

这个问题是如何产生的

我需要将数据库连接发送到子进程,以避免多次连接到这些数据库。

我的计划连接到四种不同的服务:RedisOrientDBPostgresElasticSearch

我正在做一些繁重的工作,并且需要使用多个进程并让所有进程连接到这些服务。我做了一个对象来容纳所有这些客户:

var clients = {
    redisClient: /* redis connection */
    orientClient: /* orientdb connection */
    pgClient: /* postgres connection */
    elasticClient: /* elasticsearch connection */
};

但是当我将客户端发送到子进程时:

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)

not the only one遇到了这个问题。

我对问题的解决方法

我要生成另一个处理服务的进程。其他流程将与此流程通信以与服务进行交互。

2 个答案:

答案 0 :(得分:1)

您无法将任意javascript对象传递给子进程的原因是它运行一个完全独立的V8进程,该进程不与父进程共享任何内存。

在您的情况下,我会为每个进程打开一组单独的连接。由于您不会有数百个节点进程,这对您的dbs来说不会是一个巨大的负担,它会使您的代码更简单。

(非主题)

您可以传递给另一个流程的实际情况有一个例外:您可以传递file descriptor

  

child.send(message,[sendHandle])

     

child.send()的sendHandle选项用于发送TCP服务器或   套接字对象到另一个进程。孩子将收到对象   它是消息事件的第二个参数。

cluster模块使用它。这对你的情况不是很有用,但我想我会提到:)

答案 1 :(得分:1)

不可能的一个原因是因为它不是微不足道的:如果你要在几个进程之间共享一个Redis连接,那么如何处理并发读/写?

至少在Unix类型的操作系统上,您可以在进程之间传递文件描述符,但这并不能解决并发问题。它也是非常低级的,每个Node驱动程序(Redis,OrientDB,Postgres,ElasticSearch)都会以某种方式支持传递文件句柄(他们没有,我想知道它是否可能)。

使用一个管理所有数据库连接的进程的解决方案是一个很好的解决方案,但我想知道为什么一些额外的数据库连接是一个很大的问题。