博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Node.js 之对象池
阅读量:6264 次
发布时间:2019-06-22

本文共 2314 字,大约阅读时间需要 7 分钟。

大家都知道用Node.js搭建一个简单的http服务器是多么简单的事情,打开记事本贴几句脚本,ctrl+s一下,node  server.js  一个http服务器就这样跑起来了,别看它简单,但性能丝毫不差。

 

var http = require('http');http.createServer(function (req, res) {  res.writeHead(200, {'Content-Type': 'text/plain'});  res.end('Hello Worldn');}).listen(1337, '127.0.0.1');console.log('Server running at http://127.0.0.1:1337/');

 

Node.js搭建的服务器性能如此给力确实让我很好奇它的内部是如何设计的,忍不住翻了翻lib下的代码。

 

深入了解过Node.js  http模块的同学应该知道Node.js采用一个纯c写的来实现对http报文的解析,暴露到Node.js上的是一个HTTPParser对象,在Node.js中用下面一句代码即可拿到

 

var HTTPParser = process.binding('http_parser').HTTPParser;

 

Node.js中调用c/c++内置模块采用 process.binding('module')模式,比如我们常用的setInterval和setTimeout都是基于c/c++代码实现,用 process.binding('timer_wrap').Timer即可提供js调用。

 

Node.js  http服务器每收到一个request就会用一个HTTPParser对象来解析出请求信息,比如请求参数,请求体之类的。如果说每接收一个request 都new 一个 HTTPParser对象来处理, 可以想象当并发达到成千上万时创建HTTPParser对象是多么的频繁,用完之后又立刻销毁,这种场景我们很容易想到利用多线程来处理耗时任务,为了避免频繁的创建销毁线程对象, 一般都会创建一个线程池来处理任务。于是Node.js中边产生了对象池这么个东西,也就是接下来要讲的 。

 

首先我们来看看freelist是个什么东西,和对象池有怎样的联系。

 

function FreeList(name, max, constructor) {  this.name = name;  this.constructor = constructor;  this.max = max;  this.list = [];};FreeList.prototype.alloc = function() {  return this.list.length ? this.list.shift() :                            this.constructor.apply(this, arguments);};FreeList.prototype.free = function(obj) {  //debug("free " + this.name + " " + this.list.length);  if (this.list.length < this.max) {    this.list.push(obj);  }};

 

代码相当的简单,FreeList构造函数接收3个参数,对象池名字,大小以及对象构造函数。比如在Node.js中创建一个httpParse对象池:

var parsers = new FreeList('parsers', 1000, function() {  var parser = new HTTPParser(HTTPParser.REQUEST);  parser._headers = [];  parser._url = '';  parser[kOnHeaders] = parserOnHeaders;  parser[kOnHeadersComplete] = parserOnHeadersComplete;  parser[kOnBody] = parserOnBody;  parser[kOnMessageComplete] = parserOnMessageComplete;  return parser;});

Node.js中用这段代码创建了一个叫parsers,大小为1000的对象池,当Node.js服务器接收到一个request时便向这个对象池索取一个HTTPParser对象即调用对象池parsers的alloc方法,此时便拿到了一个parser对象,parser对象解析完http报文后node并没有立即释放它,而是将它重新放入对象池parsers中,即调用parsers.free(parser),当然了只有当池子还没满的时候才可以重新被放进去。如此便实现了parser对象的重复利用,当并发数很高时极大的提升性能。

 

alt

 

相信小伙伴们应该都很清楚对象池的原理以及它在Node.js服务器中的作用了, 希望对大家在实际的业务中有所帮助哦~

 

参考文档

1.https://github.com/joyent/node/tree/master/deps/http_parser

2.https://github.com/joyent/node/blob/master/lib/freelist.js

该文章来自于阿里巴巴技术协会(ATA

作者:淘杰

转载地址:http://ebupa.baihongyu.com/

你可能感兴趣的文章
开发笔记3 | Java 代码规约第 2 条
查看>>
浅谈CSRF攻击方式
查看>>
2017 Multi-University Training Contest - Team 1 1011&&HDU 6043 KazaQ's Socks【规律题,数学,水】...
查看>>
第1天,Python入门
查看>>
canvas裁剪之后的base64转换为上传文件blob对象
查看>>
高级开发全面技能要求
查看>>
数据库主从表,主外键,表更新、删除
查看>>
JavaScript学习之旅-11(原创)
查看>>
背包九讲问题
查看>>
bootstrap模态框可拖动
查看>>
将黑苹果中的的Terminal和Bash for Windows美化了一下
查看>>
Java反射 - 字段
查看>>
sqlserver jbpm 4.4 建表语句
查看>>
如何自学图像编程
查看>>
十分钟上线-函数计算玩转wordpress
查看>>
[学习笔记] JavaScript 闭包
查看>>
手工注入 mutillidae
查看>>
线程间的协作(2)——生产者与消费者模式
查看>>
实战1:对lager测试来分析Erlang的一些特性
查看>>
input checkbox 复选框大小修改
查看>>