关于 node.js 语言的讨论
fmms 13年前
<p>本文是从 <a href="/misc/goto?guid=4958197197296387030" target="_blank">Node on nails!</a> 这篇文章翻译而来。</p> <hr /> <br /> 在开始叙述这篇文章之前,我要非常清楚和明确的声明:“我并不是在鼓励你放弃NodeJS或转向Java”。 <img title="nodejs.gif" border="0" alt="nodejs.gif" align="right" src="https://simg.open-open.com/show/cbcff49e1b9192c668336c610170a264.gif" width="90" height="90" /> <br /> <p>我一直参与在这种争论中。在我的编程界的朋友中一直存在着一种误解,他们认为NodeJS语言是将来的趋势。我对Javascript是百分百的喜 爱(不是自吹,我有一段时间曾被认为是Javascript专家,我写了很多喜欢js的文章);关于Javascript闭包的优美,原型模式编程风格的 优势,我是毫无质疑。但是,如果把Javascript放到后台,这就完全是另外一种情况了。</p> <p>每当我看到有人用一些重要的技术指标对NodeJS进行测评并<strong>宣称</strong>NodeJS是世界上最快的语言时,我都会觉得好笑。(你只要用谷歌搜一下NodeJS vs *你能想到的任何东西*,你就会找到像<a href="/misc/goto?guid=4958197198039420273" target="_blank">这样</a>, <a href="/misc/goto?guid=4958197198777814319" target="_blank">这样</a>, 和 <a href="http://www.google.com/search?client=ubuntu&channel=fs&q=nodejs+vs+php&ie=utf-8&oe=utf-8#sclient=psy&hl=en&client=ubuntu&hs=LDX&channel=fs&source=hp&q=nodejs+vs+php&pbx=1&oq=nodejs+vs+php&aq=f&aqi=p-p1g-s1&aql=&gs_sm=e&gs_upl=34998l35597l1l36170l3l3l0l0l0l0l439l1121l2-1.0.2l3l0&bav=on.2,or.r_gc.r_pw.r_cp.&fp=7f38cb74ed69968b&biw=1366&bih=658" target="_blank">这样</a>的东西。)<br /> 撇开我的质疑,NodeJS的语言模式还是值得关注的,但我会在我的产品中使用它吗?我的问题就在这。我在使用NodeJS的过程中发现了一些非常严重的 问题;给人的感觉相当的糟。我必须写一个完整的HTTP客户包来支持Multipart 方式传送(现在这个包就是人们所知的<a href="/misc/goto?guid=4958197200254250475" target="_blank">Reston</a>),这样我才能把文件发送到Amazon S3服务和其它一些REST服务里(当时没有任何支持HTTP Multipart 传送的组件,HTTPS也有问题,它折腾的我异常痛苦),总而言之,我需要向读者们说下面几个观点:</p> <ul> <li>并不是所有的web应用程序都需要<strong>大量的连接</strong>,你并不是每天都在开发一个聊天系统或一个comet系统。 NodeJS对处理某些事情很有优势,我们可以用到它。如果你是让我去在一个IRC服务器上开发一个基于websocket的聊天系统,我会推荐 NodeJS;但,如果你是让我去把邮件从你的帐号中取出然后存到RDBMS 或 NOSQL 数据库中,那我就需要思量了。</li> <li>技术架构选择很重要!接受它!运用它!我看到有些人选择了错误的技术路线(然后就炫耀说使用了NodeJS),然后又发现了更好的方法来实现他的任务,于是又放弃了NodeJS。</li> <li>如果谈论起事件为基础的代码实现和其可读性,我相信几乎每个人都会同意:回调式的代码通常比正常流程形式的代码更显得混乱。</li> <li>静态类型的语言比动态类型的语言更具有优势。如果你不了解编译器的内部工作原理,就不要理会这一条了。</li> </ul> <p>我的经验已足够用来做一次测评的了。我有一台常见的中等性能的机器(3G内存,双核处理器),做为对比,我会直接使用Java NIO来处理HTTP请求,以“hello world”做为响应;同样的过程用NodeJS实现一次。</p> <p>NodeJS代码非常的<a href="/misc/goto?guid=4958197200978667124" target="_blank">直接</a>。我使用的版本是Node 0.4.9。请注意,这个操作依赖于’http’模块,因此又依赖于’net’,’stream’等模块。这些都是NodeJS的基本功能模块(我没有做任何特别的事情),它们依赖V8的JIT来实现高速的运行。</p> <p>在Java上,我使用Java的NIP和selector 通道来实现NodeJS上的相同效果(单线程事件分发)。代码如预期中的一样,有点长,因为要做循环处理。我尽量把所有的代码都放到同一个文件里,所以,代码没有做模块化等优化。就是这两个文件:<a href="/misc/goto?guid=4958197201710931818" target="_blank">Runner.java</a> 和 <a href="/misc/goto?guid=4958197202448375260" target="_blank">core.SocketSelectorCore.java</a>。我使用了HashMaps,字符串的split,indexOf等方法来实现基本的HTTP头信息的分析,以此模拟一个普通的请求流程(读,分析,回应循环)。我使用的方法并不是很高效,但一般的时候这些方法都不是问题。</p> <p>现在使用“<em>node test.js</em>”来启动NodeJS,使用Apache Benchmark(<em>ab -c 1000 -n 100000</em>),1000的并发量[<a href="/misc/goto?guid=4958197203182196165" target="_blank">细节信息</a>],大概是每秒钟4-5千个请求的压力运行三次。</p> <p>在拿我写的Java NIO的程序测试之前,我需要提醒大家几个事情。Java是一个野兽,你有一大堆的选择参数来调控JVM的垃圾堆栈大小。在我的测试中,我使用JVM运行参数是“<em>java -server -XX:+PrintCompilation -XX:+UseConcMarkSweepGC Runner</em>”。请注意,我使用的是verbose模式的JIT编译,这样我就能知道JVM已经初始化完毕,可以开始测试了;我还改变了GC的方法(我试了各种方法,但看起来这个方法最好)。当JVM完全启动编译后,我运行了相同的Apache Benchmarks [<a href="/misc/goto?guid=4958197203914908775" target="_blank">细节信息</a>]测试,Java能处理每秒钟8千-8千5百的请求。</p> <p>我尝试了不同的JVM堆的大小和一些其它的参数;结果非常的有趣。在我的机器上,我一直能达到每秒6千的处理能力。降低并发量((-c 100),处理能力能达到11000/s。如果你仔细看,你会发现,相对于NodeJS,我在请求里封装了更多的字节,但这并没有影响Java的处理能 力。得到了这些数据后,我还使用JRuby,用它那神奇的语法写了一个很粗燥的<a href="/misc/goto?guid=4958197204651540903" target="_blank">代码</a>。对JRuby上一些参数的微调,用这个很简单的程序,我仍然能得到每秒4000-4500请求的处理能力。</p> <p>现在,剩下的问题就是,我为什么要做这些,这些说明了什么?我想答案是相当明白。从个人的角度,我喜欢Javascript和NodeJS,但我不接受人们说的“NodeJS能做<em>X</em>但<em>Y</em>语 言做不到“的言论。我认为把Java或PHP或其它语言跟NodeJS进行比较的行为是愚蠢的。Java的JIT相当的先进,而Google也把V8发展 到了一个新的高度。像Netty NIO和Mina这样的框架已经存在很久了,只是因为Java的古怪的语法,对内存的贪婪,以及学习曲线,才没有引起人们的注意。我只是要破除 “NodeJS因为它的异步特征能处理更多的连接,能让你写回调风格的代码,也就是能写出更好的代码”的谬论。我的答案相当的简单:“使用Java写核心 代码,用JRuby或Scala的优美语法封装,你会得到一个更好的处理事件驱动系统的方法”。<br /> <br /> <span style="font-weight:bold;"><a href="/misc/goto?guid=4958189735229147892" target="_blank">Node.js</a>是一套用来编写高性能网络服务器的JavaScript工具包</span>,一系列的变化由此开始。比较独特的是,Node.js会假设你是在POSIX环境下运行它Linux 或 Mac OS X。如果你是在Windows下,那就需要安装MinGW以获得一个仿POSIX的环境。在Node中,Http是首要的。Node为创建http服务器作了优化,所以你在网上看到的大部分示例和库都是集中在web上(http框架、模板库等)。<br /> <br /> 本文转载自: 外刊IT评论 <a href="/misc/goto?guid=4958183272158702965" rel="nofollow">http://www.aqee.net/</a> </p>