精华 让node.js充分利用多核服务器的性能
发布于 13 年前 作者 DoubleSpout 29849 次浏览 最后一次编辑是 8 年前 来自 分享

之前和PHP同事讨论node.js的性能问题,看了一些node.js的相关文档,node.js除了拥有非阻塞I/O,快速开发等诸多优点外,其缺点也很明显: <br/><div>1、单进程,只支持单核CPU,不能充分的利用多核CPU服务器。</div> <br/><div>2、单进程,一旦这个进程崩掉,那么整个web服务就崩掉了。(当然这个可以通过代码的健壮性来弥补)</div> <br/><div>开发环境:</div> <br/><div>vMware Red Hat 虚拟机</div> <br/><div>CPU: 两个</div> <br/><div>内存:1GB</div> <br/><div><strong><span style=“color: #ff0000”>以下有说的不对的地方还请多多指教:</span></strong></div> <br/><div><strong> <br/></strong></div> <br/><div>近期我借助node.js开发了一套网络聊天室的应用,简单实现了大厅聊天,私聊,群聊。用户信息、群组成员信息和聊天内容等借用redis进行存储。</div> <br/><div>具体聊天室的功能请参阅我的博客:<a href=“http://snoopyxdy.blog.163.com/blog/static/60117440201172510426330/”>http://snoopyxdy.blog.163.com/blog/static/60117440201172510426330/</a></div> <br/><div>现在想要1个CPU绑定一个node.js聊天室进程,需要借助这个命令:<strong><span style=“color: #ff0000”>taskset,(具体请参阅相关文档)</span></strong></div> <br/><div>在linux下运行:<span style=“color: #3366ff”><span style=“color: #3366ff”> </span></span> <br/><pre class=“prettyprint”>node server.js <br/>node server0.js</pre> <br/></div> <br/><div>我设定server.js监听端口为8888,server0.js监听端口为8889.</div> <br/><div>OK,现在2个node.js聊天室程序启动起来了。<span style=“color: #ff0000”><strong>但是要注意,这2个聊天室不能相互聊天,但是用户表是一个,就当他是两个不同的房间把。</strong></span>聊天室代码是一套,只是拷贝了一份server.js,在里面监听了不同的端口。</div> <br/><div>然后我们要对这两个node.js的进程绑定不同的CPU:(目前我的虚拟机就2个CPU)</div> <br/><pre class=“prettyprint”>ps -ef | grep node (用来查看node的进程号) <br/>root 19277 2517 15 10:12 pts/1 00:00:20 node /usr/local/node/src/chating_express/server.js <br/>root 19283 2566 18 10:13 pts/2 00:00:20 node /usr/local/node/src/chating_express/server0.js <br/>root 19291 2384 0 10:15 pts/0 00:00:00 grep node</pre> <br/><div>找到了上述2个PID后,就利用taskset来进行CPU绑定,命令如下:(这里只写其中一个)</div> <br/><pre class=“prettyprint”>taskset -pc 0 19277 (其中0代表CPU0,以此类推) <br/>pid 19277’s current affinity list: 0,1 <br/>pid 19277’s new affinity list: 0</pre> <br/><div>出现上述信息代表绑定成功,同样方法绑定另外一个。</div> <br/><div>绑定结束后我们怎么知道他们运行在不同的CPU上呢?找另外一台虚拟机,装好webbench,分别对两个node.js聊天室端口进行压力测试,然后用top命令查看各个CPU的使用情况,(小窍门,输入TOP命令,然后按数字“1”,在压力测试时不停的按“ENTER”),结果表明在压力测试server.js端口时CPU0使用率长期保持在60%以上而CPU1则使用率长期在20%以下,而测试server0.js端口时,CPU1长期保持在60%,而CPU0则保持在20%以下,结果表明绑定成功!(之前曾经乌龙了一次,用自己的虚拟机webbench压力测试,结果发现2个CPU使用率都很高,一直检查不出问题,后来发现webbench也要使用CPU的,泪奔!!!)</div> <br/><div><strong>然后安装nginx,对nginx进行配置,只需在配置文件中加入:(具体nginx的安装和设置请参阅相关文档)</strong></div> <br/><pre class=“prettyprint”>upstream node_server_pool { <br/>server 10.1.1.202:8888 max_fails=1; <br/>server 10.1.1.202:8889 max_fails=1; <br/>} <br/>server <br/>{ <br/>listen 80; <br/>server_name 10.1.1.202; <br/>location / <br/>{ <br/>proxy_pass http://node_server_pool; <br/>proxy_set_header Host 10.1.1.202:80; <br/>proxy_set_header X-Forwarded-For $remote_addr; <br/>}</pre> <br/><div>然后软重启nginx服务,访问10.1.1.202这个地址80端口,就可以让nginx做反向代理了和负载均衡了。</div> <br/><div>注:上述的这些配置需要node.js服务端代码良好的支持,session的存储建议使用redis,这样可以共享session否则需要用到ip_hash了(具体nginx优化配置请参阅相关文档),在多核CPU上跑多个node.js进程他们之间的内存是不共享的,这点需要牢记啊。</div> <br/><div>由于之前曾经压力测试过node.js的空框架,发现其内存消耗并不是很高,所以理论上来说,如果4核cpu且内存8G以上,开4个node.js进程跑在一个服务器上,用nginx做负载均衡,其性能和稳定性都应该比单个node.js提升很大。</div>

14 回复

我想问下 如果不用taskset,测试的效果是怎样的呢。

感谢jackson的关注,今天忙活了一天,终于把压力测试结果写出来了,已经提交审批了。感谢继续关注! <br/>大体结果性能提升在15%-20%左右,当然稳定更有保障了。

@snoopy <br/>都关心到进程和cpu了,老卵

聊天室的代码可以开源吗?

最后补充一下:大家比较关心的开多进程和单开性能对比,由于之后提交的压力测试结果文章一直没有被审核通过,我这里说一下: <br/>裸框架:单进程node.js和多进程node.js几乎差不多,多进程大约提升5%-10% <br/>业务处理压力:我是模拟18万次的循环浮点计算,多进程比单进程性能提升大约100%,用户响应速度提升200%,极限负载也要提升50%。 <br/>具体压测结果见:http://snoopyxdy.blog.163.com/blog/static/6011744020117315192204/

@hymnfish, <br/>聊天室的代码是学习用的,写的真的很一般,等我整理下,下周放到github上去把。

等待博主把这个聊天室的github地址中。。。

@hymnfish <br/>@xiongjiabin <br/>最近空了些,聊天室代码和演示都在: <br/>http://spout.cnodejs.net/

感谢@alsotang ,cnode 开启 html,兼容老帖

@fengmk2 应该的。。应该的。。

Node.js进程间的内存不能共享是个巨大的遗憾。

这个是nginx做,不用 cluster ?

我擦,竟是四年前的帖子

回到顶部