Node.js 官方文档上边的例子:
众所周知,当一个端口被监听的时候如果如果再次尝试监听的话,那么会报错。
下面的代码则会展示这种场景:
要尝试弄懂这个问题只有从 node.js 的源代码入手。
首先从, 入手。
可以看到,在上述的情况下,即 且 为数字或者字符串, 函数会直接调用 来处理端口的监听。事实上,如果 不为空的情况下, 也会调用 。
在 函数中,首先会判断当前的进程是否是主进程,如果是则直接进行监听,如果不是,则通过子进程查询到主进程的 ,然后在主进程的 上进行监听。
那么,这里就有一个问题,如果当前的进程没有使用 那么上述逻辑又是怎么能走得通呢。事实上。 的逻辑如下:
True if the process is a primary. This is determined by the process.env.NODE_UNIQUE_ID. If process.env.NODE_UNIQUE_ID is undefined, then isPrimary is true.
也就是说,如果进程的环境不存在 这个变量,那么都算作主进程,那么就会走主进程监听的逻辑了。
设置的逻辑如下:
那么,工作进程又是怎样找到主进程的 的呢?即 的逻辑又是怎样的呢?
所做的仅仅是向当前进程发送一个类型为 queryServer 的消息。
这个消息会被转化成 的内部消息。
这个消息会以 ( 的时候建立的,用于维持主进程与工作进程之间的通信)的形式传送给主进程。
当主进程会创建一个轮询(round-robin)的 ,基于此 创建 TCP 连接。
这一步也会走上面的 逻辑,但是由于是在主进程里执行的,因此会直接创建 TCP 连接。同时 也会覆盖 的 逻辑,将其替换成 逻辑,即此处的 。
随后, 讲当前工作进程加入 的工作队列中。
这一步完成之后,工作进程会直接返回到 的回调之中。
在 函数中,会创建一个 并交由 中进行监听。
这里直接走的 进行监听。
在 里会直接为这个 设置 回调。
这样就完成了主进程的端口监听和工作进程的连接准备工作。
当主进程的 接收到了 的请求之后,会调用 函数讲客户端的 传递给工作进程。具体的逻辑为:讲这个 保存到队列中并且从工作进程队列中获取一个空闲的工作进程。如果存在空闲的工作进程,从队列中取出一个 那么则向其发送 的消息将 传递给工作进程 。工作进程会使用此 与客户端建立连接。并发送消息给主进程。主进程通过 是否为 来判断工作进程是否接受了请求,如果是则关闭与客户端的连接,让其与工作进程进行通信。最后主进程会不断地轮询上述过程。
类似的模型 C 语言实现
领取专属 10元无门槛券
私享最新 技术干货