2

问题

为什么不能向 NodeJS 中的分叉子进程发送超过消息(字符串)?这个答案只是说明这是不可能的,但没有提供任何解释。

这个问题是怎么来的

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

我的程序连接到四种不同的服务: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)

不是唯一一个有这个问题的人。

我对问题的解决方案

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

4

2 回答 2

1

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

在您的情况下,我将为每个进程打开一组单独的连接。由于您不会有数百个节点进程,因此这不会对您的数据库造成巨大负担,并且会使您的代码更简单。

(无关)

实际上,您可以传递给另一个进程的内容有一个例外:您可以传递文件描述符

child.send(消息,[sendHandle])

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

这由集群模块使用。这在你的情况下不是很有用,但我想我会提到:)

于 2013-11-10T21:23:13.340 回答
1

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

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

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

于 2013-11-10T21:23:52.080 回答