有趣的Comet技术选择,论 Is node.js best for Comet?

首先要声明,我对Comet技术只了解皮毛,下面的评论如果有错误欢迎各位看官指出。本文相关博客地址:http://amix.dk/blog/post/19577#Is-node-js-best-for-Comet

amix在这篇博客中谈论他们在Plurk中Comet技术选择的变迁。

说句题外话,他有另外一篇博客
http://amix.dk/blog/post/19581#The-main-issue-with-non-blocking-servers
里面用两张图形象的介绍了阻塞式服务器与非阻塞式服务器的工作方式,感兴趣的可以去瞅瞅。amix关于node.js和v8的介绍可以看这里http://amix.dk/blog/post/19484#Comet-with-node-js-and-V8

关于Comet技术,可以参考维基百科 http://en.wikipedia.org/wiki/Comet_%28programming%29
国人有个开源项目http://code.google.com/p/eurasia/ 好像是做类似工作。

回到这篇博客上来,amix提到他们在项目中针对comet技术的选择,一开始是使用fast polling with C memcached nginx libevent,实现代码可以参考
http://amix.dk/blog/post/19414#Fast-polling-using-C-memcached-nginx-and-libevent
后来这个方案碰到局限了,不知什么局限,总之是不好用了。

于是实验了很多其它的comet方案,但是都不成熟。所以他们用Java与Netty实现一套comet方案,可以参考
http://amix.dk/blog/post/19456#Plurk-Comet-Handling-of-100-000-open-connections
文章里提到Twisted缺点是太耗CPU而且不易扩展;Jetty太耗内存;Tomcat也是很耗费内存;apache Mina文档不行,而且也不易扩展。最后选择了Netty,amix没有提到他们如何用Netty实现的,所以估计想用这个方案的朋友得单独联系他了。

后来amix发现node.js不错,他把java方案移植到nodejs上,只用了2天时间。在过去8个月(从2010年2月到10月)nodejs方案每天可以服务几百万用户的comet提醒。

但是,总有但是,随着网站用户增多,nodejs方案也碰到瓶颈了。即使试着做了一些优化和增加硬件,效果并不明显。amix他们又回到Netty方案,经过一些代码优化后,尽管内存使用量大于nodejs方案,但是性能要好于后者。Netty方案每秒可以为10000个客户端提供约6000个comet提醒,而Nodejs方案只能每秒服务500个,所以可以说新的Netty方案有10倍以上改进。

amix总结道,node.js是一个非常棒的方案,至少撑了8个月,而且实现起来也很快。但是nodejs有致命的缺陷。这个缺陷来自nodejs的基石-V8 JavaScript引擎。

V8引擎不支持线程或者进程机制-每件事都是主进程处理,甚至包括垃圾收集。

对于浏览器而已,这个限制是一个聪明的选择,大家知道每个Chrome页面就是一个单独的进程,所以V8引擎这种方案很好用。但是对于服务器架构就不一样了,这种单进程单线程的限制就变得麻烦。(具体为何麻烦我也不知道,也没写过nodejs项目)关于V8在服务器端使用的局限性,Nginx作者也有一篇博客介绍Why is Google V8 is not suitable for embedding in servers http://sysoev.ru/prog/v8.html 大家可以通过google翻译成英语阅读(翻译成中文后读起来很奇怪,还不如英语好懂),主要也是抱怨异常处理、进程模型、垃圾收集这几个方面。对于浏览器比较适合的V8方案,在服务器端就变成无法承受之重。

后面的回复也值得参考,其中有人提到使用nginx建立Nodejs集群然后分发,有人建议说重写nodejs的http模块很好用,也有人建议fugue这个方案http://github.com/pgte/fugue ,nodejs作者Ryan Dahl也留言说明前面版本某个bug可能导致性能问题。

偶个人的感想:即使amix有这样的抱怨,但可以看出nodejs依然是服务器端实现comet的很好选择,异步编程、高并发、低功耗,而且作者非常活跃,社区膨胀的非常快,个人感觉nodejs活跃度已经超过Lua。Lua社区有些程序员也试图用libevent或者libev来为Lua加上非阻塞异步服务器端编程的能量,但是影响力都不够,成熟度也不如nodejs。接下来偶会对nodejs做更多的探究,从源代码到小程序编写应用,希望能通过nodejs提高一下自己对服务器端编程的理解。

《有趣的Comet技术选择,论 Is node.js best for Comet?》有4个想法

  1. 我猜想,V8使用多进程的问题应该是非天生支持,要hack的东西可能会比较多,而且进程间通讯、上下文切换的几微秒消耗,对浏览器而言是无所谓,但是对于server,这种消耗是承受不起的。nginx作者的文章里好像就涉及这方面的问题。

  2. 其实Plurk 那篇博客已经看过很久了,终于看到国内有人深入翻译和研究。
    用node.js实现服务器端comet也许真的不是一个很好的选择,我用node.js开发了一个小型实时监控系统,大概700多并发。在容错(典型的如apache的多进程)、垃圾收集上确实遇到了不少问题,尤其是并发高的时候。
    并且很多时候遇到网络不稳定的时候(我这个是物联网应用),会出现很多问题,结果大量的try catch,on(error)需要处理和捕获(没办法,谁让node.js是单进程单线程呢)。
    垃圾收集确实很要命,并且很多用js开发浏览器侧web程序养成的习惯(全局变量的乱用等)在服务器端开发造成的影响也不小。

    虽然一堆抱怨,但是还是看好node.js

发表评论