Node.js V0.12新特性:Cluster轮转法负载均衡

回顾Node内置的cluster模块

Node.js固有的单线程模型经常被认为是它的一个软肋。不管你的机器上有多少CPU内核,Node.js能用上的也仅仅是其中之一(某些操作会被有条件地卸载到线程池中。大多数程序只是在CPU的总时间上分了一杯羹,所以更好地利用可用的处理能力并不能起到多大作用)。

所以Node.js从v0.8开始,新增加了一个内置的‘cluster’模块。你可以用cluster模块设置一个主进程作为管理者,由一或多个工人进程完成实际工作。

让创建“发完就忘”的多进程服务器变得更容易是其目标之一。在完美的世界中,你应该可以一行代码都不用改,就能让一个已有的单进程程序繁衍出任意多的工人进程。

当然,事情不可能那么容易,但对于没有共享状态,或共享状态很少,或把共享状态存放在数据库或Web服务之类的外部资源中的程序而言,cluster模块的确让这件事变得简单直接了。把那样的程序变成集群化的通常只需要几行代码:

var cluster = require('cluster');
    var os = require('os');

    if (cluster.isMaster)
      // 繁衍工人进程,数量跟系统中的CPU数量一样
      for (var i = 0, n = os.cpus().length; i < n; i += 1)
        cluster.fork();
    else
      // 启动程序
      app();

这个程序不需要知道它运行在集群化环境中。比如说你有一个这样的app()

var http = require('http');

    function app() {
      var server = http.createServer(function(req, res) {
        res.end('OK');
      });
      server.listen(8080, 'www.example.com');
    }

返回栏目页:http://www.bianceng.cnhttp://www.bianceng.cn/webkf/script/

cluster模块最神奇之处在于所有工人线程都可以绑定到相同的请求处理端口和地址上。另外,它可以确保接进来的连接会被均匀地分配给监听着的工人线程...最起码理论上是这样的。

Node.js v0.8和v0.10中分配连接的算法很简单。当工人进程调用http.Server#listen()net.Server#listen()时,Node.js会给主进程发送一条消息,让它创建一个服务器socket,绑定好,并分享给这个工人进程。如果已经有绑定好的socket了,主进程就会跳过“创建和绑定”那一步,只需分享已有的socket就可以了。

也就是说所有的工人进程监听的都是同一个socket。有新连接进来时,操作系统会唤醒一个工人进程。被唤醒的工人进程就会接受连接,开始提供服务。

一切都还不错。操作系统会针对运行中的进程收集大量的指标,所以应该最有资格决定唤醒哪个进程。

用现实检验理论

现在,我们进入了理论与杂乱的现实相遇的环节,因为它慢慢地水落石出了,操作系统并不能总是跟程序员想得一样做到‘最好’。特别是在某些情况下,我们观测到–特别是在Linux和Solaris中–大多数连接最终都落在了两或三个进程里。

从操作系统的角度来看这是可以理解的:上下文切换(挂起一个进程,然后重新激活另一个)是相当昂贵的操作。如果你有n个进程全都等在同一个socket上,那么唤醒最近被阻塞的进程是明智之举,因为那样可以最大限度地避免上下文切换。(当然,调度器是一种复杂而又多变的野兽;上面只是对真实情况泛泛的解释。基本前提是那些得到优待的进程会仍然受到优待)。

并不是所有的程序都会受到这个怪癖的影响,实际上大多数都不会,但那些确实会受到影响的会出现非常不均衡的负载。

一旦确定了根本原因,缓解措施就可以用上了。但还没有特别令人满意的。比如暂时放弃监听socket以便让其它工人进程有机会接受新连接,这有点儿用,但还不够。‘选定几个’中的连接数从90%下降到了60-70%,有改善,但还是不够好。更别提它对那些要处理非常短命的连接的程序的剧烈影响了。

更重要的是,我们清楚地意识到,就像随机数的生成一样,接入连接的分配太重要了,不能靠运气。经过多次讨论,我们达成了共识-我们最后,也是最好的希望是可以简单地抛弃目前的做法,切换到完全不同的东西上。这就是Node.js v0.11.2中的cluster模块换成了round-robin方式的原因,新连接由主进程接受,然后由它选择一个工人进程把连接交出去。

现在这个选择工人进程的算法还不是特别精巧。就像它的名字一样,它用的是轮转法– 只是拿起下一个可用的工人进程– 但经过核心开发人员和用户的测试,证明它很好用:连接在工人进程之间分配得很均衡。我们正在考虑将选定的算法变成可以由开发人员配置或插入的东西。

如果你还想用老办法分配连接,可以在程序中设定cluster.schedulingPolicy:

var cluster = require('cluster');
  // 在调用其他cluster函数前设定这个
  cluster.schedulingPolicy = cluster.SCHED_NONE;
  cluster.fork();

或者通过环境变量NODE_CLUSTER_SCHED_POLICY调整调度策略:

$ export NODE_CLUSTER_SCHED_POLICY="none" # "rr" is round-robin
$ node app.js

如果不想影响你的shell环境,就放在一行命令里:

$ env NODE_CLUSTER_SCHED_POLICY="none" node app.js

Windows上的注意事项

MS Windows是默认使用老办法的唯一平台。为了达到性能最优,Node.js在Windows上使用了IOCP。尽管这在大多数情况下都不错,但这样将HANDLE对象(连接)发送给其它进程代价十分高昂。 尽管有可能在libuv中解决这个问题,但我们还不清楚是否真的有必要这么做:Windows的端口几乎不会受到负载均衡问题的影响,而Linux和Solaris的端口确实会受影响。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索程序
, 模块
, 进程
, iocp
, cluster
, 进程唤醒
, node
, 一个
, Node连接数据库
js数据共享
node、node.js 安装、node.js 教程、node.js下载、node.js 视频教程,以便于您获取更多的相关知识。

时间: 2024-12-30 10:15:28

Node.js V0.12新特性:Cluster轮转法负载均衡的相关文章

Node.js V0.12新特性:性能优化

v0.12悠长的开发周期(已经过去九个月了,并且还在继续,是有史以来最长的一次)让核心团队和贡献者们有充分的机会对性能做一些优化.本文会介绍其中最值得注意的几个. 支持塞住模式的可写流 现在可写流可以支持"塞住(corked)"模式,类似于你执行man tcp时见到的socket选项TCP_CORK和TCP_NOPUSH. 当被塞住时,写到流中的数据会排队直到流被重新开塞(uncorked).这样Node.js可以将比较小的写操作合并成比较大的,从而减少系统调用和TCP往返. http

Node.js V0.12新特性之在单进程中跑多个实例

实例 经常有人提出,希望Node.js能被嵌入到其他程序中,特别是让它能跟其他事件循环整合而且(与此同时)支持多个Node执行情境:也就是说让多个Node实例在同一个进程中和平共处的能力.想象一下,比如有个node-webkit 程序,每个窗口都运行在自己的Node实例上,各窗口彼此相互独立.或者把Node嵌在手机或网络交换机里,处理多连接的路由逻辑,但却只是在单个进程中,并且不久的将来就能实现. 一个客户找到我们,说他们的程序需要这类功能.他们经过调研,肯定了我们在Node核心和libuv上的

Node.js V0.12新特性:给子进程的同步API

尽管发明Node.js的初衷主要是为了编写Web服务器,但开发人员又发现了其他适用(和不适用!)Node的用途.令人觉得惊喜的是,这些用途中有一个是编写shell脚本.并且那确实有意义:Node的跨平台支持已经相当好了,既然前端和后端都用JavaScript写了,如果构建系统也用JavaScript写不是更好吗,对吧? 异步对shell脚本的坏处 在这一用途上值得称道的库是Grunt,它是构建在ShellJS之上的.然而ShellJS有一块硬骨头要啃:Node迫使它用异步I/O.尽管对于Web服

Vue.js 2.5新特性介绍

TypeScript TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.2012年十月份,微软发布了首个公开版本的TypeScript,在2013年6月19日,微软发布了TypeScript 0.9的正式版本,到目前为止,TypeScript已发展到2.x版本,相关资料可以查看W3C TypeScript入门 安装TypeScript 安装TypeScript主要有两种方式: 通过npm

Xfce 4.12 新特性概览

Xfce 4.12 新特性概览 Xfce 4.12 经过漫长的等待终于发布了,这里向您介绍一下 Xfce 4.12的主要新特性,这里只介绍了外在的一些改进,完整的改进列表请参见  changelogs . 窗口管理器 (xfwm4) 窗口切换器对话框 窗口管理器的 Alt + Tab 对话框现已全面更换主题,还增加了两个新的模式: 列表模式和窗口预览模式.此外用户可以使用鼠标点击选择想要切换的窗口. 传统的对话框现已更换全新主题 列表模式会显示全部窗口的标题 缩略图模式 窗口预览模式会以窗口内容

IntelliJ IDEA 12新特性:为Android开发者提供新的XML重构工具

原文 http://www.cnblogs.com/nuliniaoboke/archive/2012/12/07/2807378.html 一直用IntelliJ IDEA做Android开发,感觉挺顺手.刚刚最新的IntelliJ IDEA 12(What's New?)发布,包含众多的新特性,我拣了个Android开发框架相关的特性给大家介绍下.译文如下: 最近,我们为Android XML布局文件添加了新的重构工具.所有的重构现在可以在编辑器中.UI设计器中或者直接在快捷视图中使用. 以

催化剂9.12新特性在Windows 7中的性能对比

在催化剂9.12驱动包中,我们终于看到了一次游戏性能提升,虽说不多但也聊胜于无.接下来就具体看看它和上个版本http://www.aliyun.com/zixun/aggregation/32995.html">在Windows 7里的性能对比. 催化剂9.12在新特性方面带来了对DirectCompute 10.1和OpenGL 3.2的支持,游戏性能提升则有:- 3DMark Vantage:在Radeon HD 5700/5800系列上整体性能提升最多9%,其中GT1 - Jane

深入了解Node.js中的一些特性_node.js

Node.js作为一门新兴的后台语言,旨在帮助程序员快速构建可伸缩的应用程序.Node.js有很多吸引人的地方,有关它的报道不计其数,本文将针对EventEmitter.Streams.Coding Style.Linting.Coding Style等特性进行分析探讨,帮助用户对Node.js有更深入的了解. 作为一个基于Chrome JavaScript 运行时建立的平台,我们对JavaScript 的相关认识,似乎都可应用于node应用程序之上:无需额外的语言扩展或修饰,我们便可以把前端编

新功能:阿里云负载均衡支持HTTP/2、WSS协议

很高兴的告诉大家,阿里云负载均衡在欧洲中部(法兰克福)与亚太东南3(吉隆坡)地域支持HTTP/2.WSS(Web Socket Secure)协议. 1.HTTP/2协议支持 什么是HTTP/2 HTTP2是超文本传输协议的第二版,Hypertext Transfer Protocol Version 2 (HTTP/2),向下兼容HTTP1.X协议版本,同时带来性能的大幅提升. HTTP/2相比HTTP/1.X有哪些优点 多路复用 (Multiplexing): 多路复用允许同时通过单一的 H