天天看點

Node.js 之對象池

大家都知道用node.js搭建一個簡單的http伺服器是多麼簡單的事情,打開記事本貼幾句腳本,ctrl+s一下,node  server.js  一個http伺服器就這樣跑起來了,别看它簡單,但性能絲毫不差。

node.js搭建的伺服器性能如此給力确實讓我很好奇它的内部是如何設計的,忍不住翻了翻lib下的代碼。

深入了解過node.js  http子產品的同學應該知道node.js采用一個純c寫的http_parser來實作對http封包的解析,暴露到node.js上的是一個httpparser對象,在node.js中用下面一句代碼即可拿到

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 。

首先我們來看看freelist是個什麼東西,和對象池有怎樣的聯系。

代碼相當的簡單,freelist構造函數接收3個參數,對象池名字,大小以及對象構造函數。比如在node.js中建立一個httpparse對象池:

node.js中用這段代碼建立了一個叫parsers,大小為1000的對象池,當node.js伺服器接收到一個request時便向這個對象池索取一個httpparser對象即調用對象池parsers的alloc方法,此時便拿到了一個parser對象,parser對象解析完http封包後node并沒有立即釋放它,而是将它重新放入對象池parsers中,即調用parsers.free(parser),當然了隻有當池子還沒滿的時候才可以重新被放進去。如此便實作了parser對象的重複利用,當并發數很高時極大的提升性能。

Node.js 之對象池

相信小夥伴們應該都很清楚對象池的原理以及它在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)

作者:淘傑

繼續閱讀