玩转Nodejs的集群

在Nodejs中使用集群还是不容易的。Javascript的单线程属性让nodejs下的应用很难使用现代机器的多核特性。比如下面的代码实现了一个http服务器的主干部分。这部分代码只会执行在一个线程上,不管这段代码运行的机器是单核的cpu还是1000个内核的cpu。

var http = require("http");
var port = parseInt(process.argv[2]);

http.createServer(function(request, response) {
  console.log("Request for:  " + request.url);
  response.writeHead(200);
  response.end("hello world\n");
}).listen(port);

使用多核特性

只需要一点修改,上面的代码就可以把cpu的所有核心都用起来。上面的示例代码将使用cluster模块重构。cluster模块可以让你很容易的创建多个分享端口的进程。每一个进程使用一个系统核心,也就是代码中的numCPUs变量中cpu核心的一个。每一个子进程都实现了HTTP server,并监听指定的端口。

var cluster = require("cluster");
var http = require("http");
var numCPUs = require("os").cpus().length;
var port = parseInt(process.argv[2]);

if (cluster.isMaster) {
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on("exit", function(worker, code, signal) {
    cluster.fork();
  });
} else {
  http.createServer(function(request, response) {
    console.log("Request for:  " + request.url);
    response.writeHead(200);
    response.end("hello world\n");
  }).listen(port);
}

多机器的均衡

使用cluster模块,你就可以更高效的使用硬件。然而,你还是被限制在单一的机器上。如果你的应用有客观的访问量,你最终还是把负载分部在不同的机器上。使用reverse proxy server可以把并发的访问负载到不同的服务器上。

Nodejitsu开发了node-http-proxy模块,一个开源的nodejs应用代理服务。使用以下命令可以安装这个模块:

npm install http-proxy

实际的使用可以参考以下代码。在这里例子中负载被分发到两台服务器上。首先测试反转代理,确保HTTP server运行在8080和8081两个端口上。接下来,运行反转代理,然后用浏览器访问这个代理。如果一切正常的话,你会发现请求被两个服务器交替处理。

var proxyServer = require(‘http-proxy‘);
var port = parseInt(process.argv[2]);
var servers = [
  {
    host: "localhost",
    port: 8081
  },
  {
    host: "localhost",
    port: 8080
  }
];

proxyServer.createServer(function (req, res, proxy) {
  var target = servers.shift();

  proxy.proxyRequest(req, res, target);
  servers.push(target);
}).listen(port);

当然,这个例子只使用了一台机器。然而,如果你有多台机器的话,你可以在一台机器上运行反向代理服务器,其他的机器上运行HTTP server。

使用nginx负载均衡

使用nodejs写的反向代理有一个好处是你使用的技术都是一样的。但是,在生产环境下,更多使用的是nginx来处理负载均衡。nginx是一个开源的HTTP server和反向代理工具,尤其擅长处理静态文件,比如:CSS和HTML。因此,nginx常被用于处理站点的静态文件,和分发动态请求到nodejs的服务器上。

要实现nginx的负载均衡,只需要安装nginx,之后把nodejs服务器作为upstream resource添加在配置文件中。配置文件的路劲一般是{nginx-root}/conf/nginx.conf,{nginx-root}是nginx安装的根目录。整个的配置文件请参考下面的示例。当然,我们只需要用到其中的一小部分。

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  ‘$remote_addr - $remote_user [$time_local] "$request" ‘
    #                  ‘$status $body_bytes_sent "$http_referer" ‘
    #                  ‘"$http_user_agent" "$http_x_forwarded_for"‘;

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    upstream node_app {
      server 127.0.0.1:8080;
      server 127.0.0.1:8081;
    }

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location /foo {
          proxy_redirect off;
          proxy_set_header   X-Real-IP            $remote_addr;
          proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
          proxy_set_header   X-Forwarded-Proto $scheme;
          proxy_set_header   Host                   $http_host;
          proxy_set_header   X-NginX-Proxy    true;
          proxy_set_header   Connection "";
          proxy_http_version 1.1;
          proxy_pass         http://node_app;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache‘s document root
        # concurs with nginx‘s one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

    # HTTPS server
    #
    #server {
    #    listen       443;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers   on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

如前文所述,本教程只会涉及到整个配置文件的一部分。第一个需要关注的部分如下所示。

upstream node_app {
  server 127.0.0.1:8080;
  server 127.0.0.1:8081;
}

这部分的配置定义了一个upstream服务器,名称为node_app。对这个服务器的请求会分配到就两个ip地址上(这里只用端口区分了一下)。

只是定义了一个upstream服务器还没有告诉nginx如何使用它。因此,我们必须使用如下的指令顶一个路由的规则。使用这个路由,任何的到/foo的请求都会被代理到之前配置的nodejs服务器上。

location /foo {
  proxy_redirect off;
  proxy_set_header   X-Real-IP            $remote_addr;
  proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  proxy_set_header   X-Forwarded-Proto $scheme;
  proxy_set_header   Host                   $http_host;
  proxy_set_header   X-NginX-Proxy    true;
  proxy_set_header   Connection "";
  proxy_http_version 1.1;
  proxy_pass         http://node_app;
}

最后

本教程旨在介绍如何把单线程的Nodejs应用运行在多台机器的多个核心上。你也可以学到如何使用nodejs或者nginx建立一个负载均衡。当然本文不是深入的介绍如何在产品环境下运行的。因此,如果你使用的是nginx,还有很多其他的可以做的,比如缓存,来提高系统性能。你也会需要使用forever,如果崩溃的话这个工具可以重启你的nodejs进程。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-15 04:08:33

玩转Nodejs的集群的相关文章

教你玩转Hadoop分布式集群搭建,进击大数据

yuuuqw淌靠拘心重瞻伊米志顺http://blog.sina.com.cn/s/blog_17bd9025e0102x97r.htmlm2g4qb晕刚颇即蒲乘啬捞泌窒http://blog.sina.com.cn/s/blog_170e51b9a0102y3tz.htmla6wasu颖掀痘悦匝抑道磺焉卸http://blog.sina.com.cn/s/blog_170e508f20102x363.htmlwsyswm滩丈绞液勾赘曝胁汗兄http://blog.sina.com.cn/s/b

mongodb高可用集群02---副本集

本人根据此文章进行学习:http://blog.jobbole.com/72624/ 会不断更新内容主要分为四大模块: mongodb各种方式的部署 常用使用[工作不用就没必要学了,精力有限] 性能优化 故障排除 很多会和网上资料一样,主要是自己学习不断梳理资料,追求:提及精华 1)副本集概念: 副本集合(Replica Sets),是一个基于主/从复制机制的复制功能,但增加了自动故障转移和恢复特性.一个集群最多可以支持7个服务器,并且任意节点都可以是主节点.所有的写操作都被分发到主节点,而读操

Apache+Tomcat +mod_proxy集群负载均衡及session

  序言: 在玩Apache+Tomcat +mod_jk集群负载均衡及session的时候发现,还有一种方式可以实现,就是网上各位大牛们说的mod_proxy反向代理. 实在弄的我的知识细胞洋洋.实践后打个报告,给自己.. 环境说明: 操作系统:win7   64位 Javajdk: 1.7 Apache:httpd-2.2.25-win32-x86-no_ssl.msi    (本地安装路径:D:\Program Files (x86)\Apache2.2\)Tomcat: 7.0.42 

想玩集群?读写分离?你要先懂这个!

答案是:Mysql主从同步,集群,读写分离,都会涉及数据的数据同步,所以想玩哪些东西,我们还是要把这个数据同步的基础学会之后我们才能玩其他的,今天呢思梦PHP就给大家带来了这个小案例,亲测,没毛病! 以下案例是测试案例,当然你线上服务器也是一样的!首先你要保证的你的操作系统的统一,数据库的版本的统一你才能开启数据同步的大门!下面就上步骤了! 1:首先你需要一个虚拟机,然后上面配置两个系统,当然你的mysql的版本要保持一致 2:你在你主的mysql里面创建一个你要同步的mysql数据库 3:Li

菜鸟玩云计算之十八:Hadoop 2.5.0 HA 集群安装第1章

菜鸟玩云计算之十八:Hadoop 2.5.0 HA 集群安装第1章 cheungmine, 2014-10-25 0 引言 在生产环境上安装Hadoop高可用集群一直是一个须要极度耐心和体力的仔细工作. 虽然有非常多文档教会大家怎么一步一步去完毕这样的工作,可是百密也有一疏. 现成的工具不是没有,可是对于我这个喜欢了解细节的人来说,用别人的东西,写的好还能够,写的不好,出了问题,查找错误难之又难.手工安装Hadoop集群须要对Linux有一定的使用经验.对于全然没有接触Linux的人来说.肯定是

5 秒创建 k8s 集群 - 每天5分钟玩转 Docker 容器技术(115)

据说 Google 的数据中心里运行着超过 20 亿个容器,而且 Google 十年前就开始使用容器技术. 最初,Google 开发了一个叫 Borg 的系统(现在命令为 Omega)来调度如此庞大数量的容器和工作负载.在积累了这么多年的经验后,Google 决定重写这个容器管理系统,并将其贡献到开源社区,让全世界都能受益. 这个项目就是 Kubernetes.简单的讲,Kubernetes 是 Google Omega 的开源版本. 从 2014 年第一个版本发布以来,Kubernetes 迅

用 Weave Scope 监控集群 - 每天5分钟玩转 Docker 容器技术(175)

创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所有必要组件就位并各司其职,有足够的资源满足应用的需求.Kubernetes 是一个复杂系统,运维团队需要有一套工具帮助他们获知集群的实时状态,并为故障排查提供及时和准确的数据支持. 本章重点讨论 Kubernetes 常用的监控方案,下一章会讨论日志管理. Weave Scope Weave Scope 是 Docker 和 Kubernetes 可视化监控工具.Scope 提供了至上而下的集群

Kubernetes 集群日志管理 - 每天5分钟玩转 Docker 容器技术(180)

Kubernetes 开发了一个 Elasticsearch 附加组件来实现集群的日志管理.这是一个 Elasticsearch.Fluentd 和 Kibana 的组合.Elasticsearch 是一个搜索引擎,负责存储日志并提供查询接口:Fluentd 负责从 Kubernetes 搜集日志并发送给 Elasticsearch:Kibana 提供了一个 Web GUI,用户可以浏览和搜索存储在 Elasticsearch 中的日志. 部署 Elasticsearch 附加组件本身会作为 K

支撑微博亿级社交平台,小白也能玩转Redis集群(原理篇)

Redis作为一款性能优异的内存数据库,支撑着微博亿级社交平台,也成为很多互联网公司的标配.这里将以Redis Cluster集群为核心,基于最新的Redis5版本,从原理再到实战,玩转Redis集群 常见Redis集群方案 在介绍Redis Cluster集群方案之前,为了方便对比,先简单了解一下业界常见的Redis集群方案: 1 基于客户端分片 Redis Sharding是Redis Cluster出来之前,业界普遍使用的多Redis实例集群方法.其主要思想是基于哈希算法,根据Redis数