Created
March 30, 2014 17:05
-
-
Save adohe-zz/9875982 to your computer and use it in GitHub Desktop.
deep info about cluster&child_process
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| The truth of cluster&child_process module | |
| 周五的tech_talk中关于cluster和child_process这块的知识讲的不是很好,同时多少也有些 | |
| 问题,所以利用周天的时间再写点关于这方面的杂文,加深下自己的了解(PS:这么好的天气实在 | |
| 是应该出去赏樱花而不是在这里写东西啊,好像出去找个草坪躺在上面写也不错嗒!) | |
| 感叹到此为止,言归正传,Node在v0.8版本时新增了cluster模块,用于解决多核CPU的利用率 | |
| 问题,同时也提供了完善的API,用于处理进程的健壮性问题。在v0.8版本之前,要实现多进程架 | |
| 构只能通过child_process模块,考虑到有很多细节问题需要处理,可想而知这不是一件简单的事 | |
| 情。好在我们有cluster,事实上cluster模块就是child_process模块和net模块的结合。cluster | |
| 启动时,它会在内部启动TCP服务器,在cluster.fork()子进程时,将这个TCP服务端socket的文件 | |
| 描述符发送给工作进程,如果工作进程中存在listen()侦听网络端口的调用,它将拿到该文件描述 | |
| 符,通过SO_REUSEADDR端口重用,从而实现多个子进程共享端口。关于cluster模块的使用,在上周 | |
| 的tech_talk已经讲的很清楚,这里推荐采用cluster.setupMaster()的方式而不是使用cluster.isMaster | |
| 来进行判断,这样程序结构不再凌乱,逻辑分明,代码的可读性和可维护性较好。 | |
| 终于该说到重点了,在这篇杂文中,我重点想说的是当我们在使用cluster和child_process | |
| 模块的时候,如果主进程意外退出(比如说被kill),这个时候子进程会怎样。首先来说说cluster | |
| 模块,其实不论是使用cluster还是child_process实现多进程架构,它的模式都是Master-Worker | |
| 模式,这是典型的分布式架构中用于并行处理业务的模式,具备较好的可伸缩性和可扩展性。主进程 | |
| 不负责具体的业务处理,而是负责调度和管理工作进程,它是趋向于稳定的。工作进程负责具体的 | |
| 业务处理。在Node较早的cluster的实现中,当master die的时候,workers是不会被kill的,这个 | |
| 时候这些worker process就会变成孤儿进程被init进程接管(*nix平台上的情形),但是这个bug在随 | |
| 后的cluster 2.0的实现中被fix,也就是说现在当master die的时候,all workers will be killed. | |
| (PS:这个不会是受eBay开源的cluster2的影响吧!!!),在我最新上传的gists中有关于cluster的测试, | |
| 可以证明这一点,有兴趣的童鞋可以去看看。 | |
| 接下来是child_process模块,child_process模块给予Node可以随意创建子进程的能力。它提供了 | |
| 四个方法用于创建子进程:spawn(), exec(), execFile(), fork(){实际上后面三种方法都是对spawn() | |
| 的延伸应用,例如fork('./child.js'),实际上相当于spawn('node', ['./child.js'])},所以在我们 | |
| 使用child_process去创建子进程的时候,如果master crash的时候,子进程会怎样呢?为了回答清楚 | |
| 这个问题我们需要了解以下fork()的工作原理:实际上通过fork()复制的进程都是一个独立的进程, | |
| 这个进程中有着独立而全新的V8实例。在我们最新的test脚本中(即将上传到gist),我们发现当主进程 | |
| 退出的时候,工作进程并不会马上退出,相反它会被init进程接管,也就是我们所说的孤儿进程,所以 | |
| 当我们在使用child_process模块实现多进程架构的时候,需要特别注意这些细节问题。 | |
| 最后我想再谈谈multi process share memory的问题,实际上在Node进程中是不宜存放太多的数据 | |
| 的,因为它会加重垃圾回收的负担,进而影响性能。同时,Node也不允许在多个进程之间共享数据, | |
| so memory sharing is impossible but buffer objects can be shared. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
那就是说,node.js fork process 时强行做了 data (heap) copy instead of COW?