Nginx与JS均是事件驱动。 Nginx可以做负载均衡,充分使用异步逻辑,削减了上下文调度开销,来实现很强的并发服务能力; node通过事件模型及回调实现异步,亦可获得很好的性能。 想了解一下这两者关于实现方面,以及架构思路层面有哪些具体的异同? 欢迎讨论。
个人理解:假如有一个8核cpu,主进程 fork 8个子进程,nginx为了追求更好的并发服务能力,是每个子进程都监听连接,但是会产生惊群,所以nginx内部自己用互斥锁来解决惊群。而nodejs服务器 是只有主进程监听连接,然后再把连接均衡的分给各个子进程(因为nodejs不必追求nginx的极致性能),虽然仅有一个进程去accept,然后通过消息队列等同步方式使其他子进程处理这些新建的连接,效率会低一些,但是不会惊群。
@JustforNode 内核早就解决了“惊群”问题了。(大概是 2.6 版本之后吧)
@yszou 具体解决方案是什么?
@yakczh fork 之后,accept 自己就不会多次触发啊。
node 跟 nginx 不是一个层面的东西啊。
nginx 作为应用层服务器,以系统级的 epoll 之类机制为基础,往上是需要完整,完美,实现 http 协议的,然后是应用层上的各种附加功能,它需要把这些附加功能实现得“简单易用”。
node 只是给 js 加了一套运行时环境而已,它本身,本来应该是不关注具体应用场景的。但是,也许是因为 js 或者 v8 本身的原因, node 的 api 大部分要搞成异步的,这在非网络IO场景下,就是一个反人类的东西(可能在 GUI 场景也需要吧,这方面了解不多了,但是没听说过 node 能把 Qt, GTK 之类的搞好)。 而在网络IO场景下,其它语言也仍然可以支持 epoll ,也一样是异步。node 的性能,不是因为它的事件模型,而是 v8 的功劳。
(对了,node 适用于网络IO场景,基本上也根本不需要什么 fork 子进程,你直接在外部就启动 N 个进程,然后反向代理一下就完了)
想了解一下这两者关于实现方面,以及架构思路层面有哪些具体的异同?
你要比架构思路,应该拿 nginx 跟 apache 比。 拿 node 跟 php, python, ruby 比。其实跟后两者也没什么好比的,人家是很“正常”的从语言层面开始的实现,而 node 是先有语言,再套的运行时。跟 php 倒是可以比比, php 算是从 DSL 进化到现在这种程度的。
@yszou 你确定nginx是只有主进程accept?
@JustforNode 我指的是它里面写的这部分内容(其它内容没细看):
其实,在linux2.6内核上,accept系统调用已经不存在惊群了(至少我在2.6.18内核版本上已经不存在)。大家可以写个简单的程序试下,在父进程中bind,listen,然后fork出子进程,所有的子进程都accept这个监听句柄。这样,当新连接过来时,大家会发现,仅有一个子进程返回新建的连接,其他子进程继续休眠在accept调用上,没有被唤醒。