1、multi-node

node只能单进程,单cpu工作,而multi-node则可以让node在多进程下共享内存的工作,实现机制是依靠child_process的sendmsg做到的。想要了解具体实现原理请查阅multi-node的源代码。
我们可以从github上下载到最新版本的multi-node,地址是:https://github.com/kriszyp/multi-node
他的具体用法也非常的简单,我们看示例代码:
 
 
var server = require("http").createServer(function(request, response){
  //这里是处理请求的程序
 });
 var nodes = require("multi-node").listen({
port: 80,     //监听的端口
nodes: 4    //打开node进程数,一般最多为服务器CPU个数
 }, server);
 
这样使用 $ node server.js就会启动4个server.js来监听80端口,具体请求被分配到哪个进程,由multi-node控制。在进程之间通信可以利用他提供的Framing,也可以利用redis等内存db来做。
 
nodes.addListener("node", function(stream){
    stream = require("multi-node").frameStream(stream);
    stream.addListener("message", function(data){
           //在这里接受从其他进程发送的数据,可以是字符串,对象或其他格式
    });
    stream.send({foo:"bar"}); //类似广播概念,给所有进程广播这个消息
});
 
单进程"hello world"node服务器,在4CPU 3.4GHZ服务器上压测是4000qps+,开了multi-node以后再测试可以稳定达到7500qps+以上,峰值在8500qps+,性能大幅度提高。
 
2、generic-pool
generic-pool是一个通用连接池,node和php不同,php每次和db通信,都需要先建立连接然后执行程序,最后释放这个连接。node是可以事先建立一个池子,然后根据需要生成连接放入这个池中,当node要和db通信时则去池子中拿连接,用完以后不释放,而是将这个连接归还到池中,我们也可以设定这个池子的的最大连接数和闲置连接超时释放的时间。
1、可以不必为建立连接和释放连接消耗更多的响应时间,一个连接在高并发下可以被高度重用。
2、有队列机制,当池子中连接都用完了,其他请求在排队时,有一些紧急的任务需要插队,我们可以很方便的做到这点。
我们可以从github上下载到最新版本的generic-pool,地址是:https://github.com/coopernurse/node-pool
他的示例代码是为mysql提供连接池,我就不贴上来了,我们来为redis做一个简单的链接池,并测试下。先简单介绍下他的几个参数:
 
 name : name of pool (string, optional)
 create : function that returns a new resource
              should call callback() with the created resource
 destroy : function that accepts a resource and destroys it
 max : maximum number of resources to create at any given time
 idleTimeoutMillis : max milliseconds a resource can go unused before it should be destroyed
                         (default 30000)
reapIntervalMillis : frequency to check for idle resources (default 1000),
priorityRange : int between 1 and x - if set, borrowers can specify their
                         relative priority in the queue if no resources are available.
                         see example.  (default 1)
 log :  true/false or function -
          If a log is a function, it will be called with log strings 
          Else if log is true, verbose log info will be sent to console.log()
          Else internal log messages be ignored (this is the default)
 
英文好的朋友很容易就看懂了上面的这些说明,我为英文和我一样比较差的朋友简单翻译一下,省的他们再去google翻译了。
 
name:连接池的名字,例如“mysql”,主要是用作日志上的区分,一个名字而已
create:一个函数,和db建立连接的函数,必须要把创建好的db连接示例传入到callback函数中
destroy:摧毁和这个db连接的函数
idleTimeoutMillis:为每个连接设置一个超时时间
reapIntervalMillis:检查闲置连接的频率
priorityRange:1-X的整数,当没有连接时,可以为1-X这几个应用开辟绿色通道,让他们插队。
log:日志系统,true的话则是记录详细日志,开发时用,一般为false
 
下面我就贴一段redis连接池的代码:
 
var poolModule = require('./generic-pool.js');
    var pool = poolModule.Pool({
        name     : 'redis',
        create   : function(callback) {
            var client = require('redis').createClient();  //这里是创建redis连接实例的代码
            callback(null, client);  //创建完了以后,要把client传给callback,这里第一个参数看了源码得知是err,我们不必理会
        },
        destroy  : function(client) { client.quit(); }, //当超时则释放连接
        max      : 10,   //最大连接数
        idleTimeoutMillis : 30000,  //超时时间
        log : true,  
    });
 
下面我可以利用他提供的几个方法,用连接池来操作redis:
 
 var test_pool =function(){
 pool.acquire(function(err, client) {
       client.set('test', 'xdy',function(err, reply){
console.log(reply+"");
pool.release(client);
})
    });
 pool.acquire(function(err, client) {
       client.set('test1', 'xdy',function(err, reply){
console.log(reply+"");
pool.release(client);
})
    });
 pool.acquire(function(err, client) {
       client.set('test2', 'xdy',function(err, reply){
console.log(reply+"");
pool.release(client);
})
    });
 }
 test_pool ();
setTimeout(function(){
test_pool ();
},500);
 
我们定义了一个test_pool的方法,定义了3个redis操作,使用pool的acquire方法来去连接池拿连接,在处理完毕以后,用pool的release方法将连接归还到连接池,我们打开日志,运行程序以后可以看到:
在test_pool()执行后,连接池创建了3个连接给test_pool,test_pool在redis操作完毕以后,归还连接,在500毫秒之后,test_pool再次去连接池拿连接操作redis,这时因为之前的连接没有超时,所以之前的3个连接又被拿出来处理第二次test_pool函数了。这样就做到了重用,不必每次去建立和释放连接,当30秒过后,连接会自动释放掉。
 
个人觉得我们还可以对这个连接池改写一下,再提高一下连接池在某些情况下的性能,为连接池增加一项配置,就是永不过期的连接数,这样我就可以在程序启动的时候预先放置好一些连接永不过期,如果大并发突然过来可以节约一点创建连接的时间,这种情况比较少,改写以后可能压力测试成绩会好一点。
 
具体压测数据,请关注我博客,我将会在和PHP对比压测文章内给出。

multi-node和generic-pool两大利器的更多相关文章

  1. 264分析两大利器:264VISA和Elecard StreamEye Tools

    学了264有将近3个月有余,好多时候都在学习老毕的书和反复看JM86的代码,最近才找到264分析两大利器:264VISA和Elecard StreamEye Tools.不由得感叹,恨不逢同时. 简单 ...

  2. Spring Security和 JWT两大利器来打造一个简易的权限系统。

    写在前面 关于 Spring Security Web系统的认证和权限模块也算是一个系统的基础设施了,几乎任何的互联网服务都会涉及到这方面的要求.在Java EE领域,成熟的安全框架解决方案一般有 A ...

  3. 如何使用 K8s 两大利器"审计"和"事件"帮你摆脱运维困境?

    概述 下面几个问题,相信广大 K8s 用户在日常集群运维中都曾经遇到过: 集群中的某个应用被删除了,谁干的? Apiserver 的负载突然变高,大量访问失败,集群中到底发生了什么? 集群节点 Not ...

  4. 告别set和get,两大利器轻松搞定model转换

    场景一:一般我们遇到需要新建model,常规做法就是创建一个类,老老实实的定义好model中的所有属性,一般来说属性对应的set方法和get方法都是少不了的,有时候还需要toString甚至equal ...

  5. 转: H264码流分析 --264分析两大利器:264VISA和Elecard StreamEye Tools

    转码: http://www.360doc.com/content/13/0225/19/21412_267854467.shtml ESEYE视频工具全称是什么: Elecard StreamEye ...

  6. .Net 两大利器Newtonsoft.NET和Dapper

    你可以使用ado.net返回的DataTable让Newtonsoft.NET来序列化成Json. 当然你可以使用Dapper返回的List让Newtonsoft.NET来序列化成JSON. 参考资料 ...

  7. webpack 教程 那些事儿03-webpack两大精华插件,热加载

    本节主要讲述 webpack的两大经典开发调试插件,热插拔内存缓存机制 文章目录 1. html-webpack-plugin插件的使用 2. webpack-dev-middleware 插件登场 ...

  8. [转帖]两大容器管理平台,Kubernetes与OpenShift有什么区别?

    两大容器管理平台,Kubernetes与OpenShift有什么区别? https://www.sohu.com/a/327413642_100159565 原来openshift 就是 k8s的一个 ...

  9. 3dTiles 数据规范详解[3] 内嵌在瓦片文件中的两大数据表

    转载请声明出处:全网@秋意正寒 零.本篇前言 说实话,我很纠结是先介绍瓦片的二进制数据文件结构,还是先介绍这两个重要的表.思前想后,我决定还是先介绍这两个数据表. 因为这两个表不先给读者灌输,那么介绍 ...

随机推荐

  1. iOS开发SDWebImage的基本使用

    #import "ViewController.h" #import "UIImageView+WebCache.h" #import "SDWebI ...

  2. Deepin系统更新apt-get源

    1.复制原文件备份sudo cp /etc/apt/source.list /etc/apt/source.list.bak2.编辑源列表文件sudo vim /etc/apt/source.list ...

  3. 教你如何利用php.exe运行php文件

    教你如何利用php.exe运行php文件 一.总结 一句话总结:就是使用的php.exe,和java中的javac一样,都是有exe,然后有了对应命令,比如php.exe,然后就可以用php命令. 1 ...

  4. 2015年工作中遇到的问题:71-80,Tomcat-Redis-浮点数-HTTPS

    71.Tomcat访问项目带了"项目名称".最简单的办法,是把这个项目部署到"root"目录,据boss所说,阿里的每一个项目,都单独放到1个Tomcat的ro ...

  5. 【rlz000】字串找数

    Time Limit: 3 second Memory Limit: 2 MB 问题描述 输入一个字符串,内有数字和非数字字符.如A123X456Y7A,302ATB567BC,统计共有多少个整数, ...

  6. MapReduce wordcount 输入路径为目录 java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$POSIX.stat(Ljava/lang/String;)Lorg/apache/hadoop/io/nativeio/NativeIO$POSIX$Stat;

    之前windows下执行wordcount都正常,今天执行的时候指定的输入路径是文件夹,然后就报了如题的错误,把输入路径改成文件后是正常的,也就是说目前的wordcount无法对多个文件操作 报的异常 ...

  7. myeclipse codelive插件关闭

    开启这个插件时,当你运行web工程,打开页面会造成一些显示的问题,原因是codelive插件向你的页面代码中注入了一些js代码大概是如下这些 <script>"undefined ...

  8. 报错:javax.servlet.jsp.PageContext cannot be resolved to a type;javax.servlet.jsp.JspException cannot be resolved to a type

    Multiple annotations found at this line: - javax.servlet.jsp.PageContext cannot be resolved to a typ ...

  9. 编译和使用jasper库的一个注意事项

    作者:朱金灿 来源:http://blog.csdn.net/clever101 由于jasper库是一个跨平台库,而Windows的VC编译器和Linux的GCC编译器的头文件并不完全一致(可能因为 ...

  10. Variability aware wear leveling

    Techniques are presented that include determining, for data to be written to a nonvolatile memory, a ...