2013-09-27 102 views
31

有人能解釋如何使用request.js池哈希?如何使用請求JS(節點JS模塊)池

github notes說,這大約池:

池 - 包含這些請求代理的哈希對象。如果省略,則該請求將使用設置爲節點的默認maxSockets的全局池。

pool.maxSockets - 包含在池中的套接字的最大量整數。

我有寫這個代碼寫入一個CouchDB實例(注意問號)。基本上,誰連接到我的節點服務器的任何用戶將寫信給對方的DB獨立:

var request = require('request'); 

request({ 
    //pool:,  // ?????????????????? 
    'pool.maxSockets' : 100, // ?????????????????? 
    'method' : 'PUT', 
    'timeout' : 4000, 
    'strictSSL' : true, 
    'auth' : { 
     'username' : myUsername, 
     'password' : myPassword 
    }, 
    'headers' : { 
     'Content-Type': 'application/json;charset=utf-8', 
     'Content-Length': myData.length 
    }, 
    'json' : myData, 
    'url': myURL 
}, function (error, response, body){ 
    if (error == null) { 
     log('Success: ' + body); 
    } 
    else { 
     log('Error: ' + error); 
    } 
}); 

什麼是最好的高吞吐量/性能?
高'maxSockets'數字有什麼缺點?
如何創建一個單獨的池來使用而不是全局池?爲什麼我只想創建一個單獨的池?

回答

38

在請求池中選項使用劑是相同http.Agent從標準的HTTP庫。請參閱http.Agent的文檔,並參閱http.request中的agent選項。

使用

pool = new http.Agent(); //Your pool/agent 
http.request({hostname:'localhost', port:80, path:'/', agent:pool}); 
request({url:"http://www.google.com", pool:pool }); 

如果你想知道那是什麼,你可以從控制檯中看到它。

{ domain: null, 
    _events: { free: [Function] }, 
    _maxListeners: 10, 
    options: {}, 
    requests: {}, 
    sockets: {}, 
    maxSockets: 5, 
    createConnection: [Function] } 

maxSockets決定有多少併發套接字代理可以爲每個主機的開放,是默認值爲5.通常,您將之前設置的代理存在。顯式傳遞pool.maxSockets將覆蓋pool中的maxSockets屬性。此選項只有在傳遞pool選項時纔有意義。

所以不同的方式來使用它:

  1. 不要給agent選項,將undefined將使用http.globalAgent。默認情況。
  2. 將其作爲false將會禁用共享池。
  3. 提供您自己的代理,就像上面的例子。

以相反的方式回答您的問題。

池是爲了保持一定數量的套接字被程序使用。首先,套接字被重用於不同的請求。所以它減少了創建新套接字的開銷。其次,它使用較少的套接字來處理請求,但始終如一。它不會佔用所有可用的插座。第三,它維護請求隊列。所以有暗示的等待時間。

池充當緩存和節流閥。如果你有更多的請求和更少的套接字,節流效果將更明顯。使用全局池時,可能會限制兩個不同客戶端的功能,等待時間沒有保證。爲他們分開游泳池將會更公平(想想如果有人要求比其他更多)。

maxSockets屬性提供了最大的併發可能性。它增加了整體吞吐量/性能。缺點是節流效果降低。您無法控制峯值開銷。將它設置爲大數目,將會像沒有共享池一樣。你會開始得到像socket這樣的錯誤不可用。它不能超過操作系統所允許的最大限制。

那麼什麼是最好的高吞吐量/性能?吞吐量有物理限制。如果達到極限,響應時間將隨着連接數量的增加而增加。到那時你可以繼續增加maxSockets,但在增加之後它不會有幫助。

+0

在你的第一個使用示例中,第二行'http.request({...})的含義是什麼? - 這僅僅是爲了表明它在使用核心HTTP模塊時工作,或者是需要聲明被調用是爲了正確地初始化在'request'庫中使用的池?謝謝! – 2016-07-01 04:26:22

+0

您的回答是我迄今爲止獲得的關於代理池和使用它們的利弊的最佳資源。非常感謝您花時間編寫這個(y) –

+0

**注意**最近版本的_Node.js_在默認情況下具有'Infinity'作爲'maxSockets'。 –

13

你應該看看forever-agent模塊,這是一個包裝http.Agent

通常該池是包含多個HTTP代理的散列對象。它試圖從「保持活動」連接中重用創建的套接字。每主機:端口。例如,您執行了多個請求來託管www.domain1.com:80和www.domain2.com:80,如果任何響應中不包含標頭Connection: close,它會將該套接字放入池中並將其提交給未決請求。

如果沒有掛起的請求,需要這個彙集插座,它就會被破壞。

maxSockets表示單個主機端口的最大併發套接字,默認值爲。我會建議你一起考慮這個價值與你的情況:

  • 根據那些熱點請求訪問,你最好創建單獨的池。所以新的請求可以非常快速地提取空閒套接字。問題是,您需要通過增加池的值來減少對某些站點的未決請求數。請注意,當連接由原始服務器通過響應標頭Connection: close管理良好時,如果將極高數字設置爲maxSockets,則無關緊要。

  • 根據這些,你的請求很難訪問的網站,使用pool: false禁用池。

您可以用這種方式來指定不同的池您的要求:

// create a separate socket pool with 10 concurrent sockets as max value. 
var separateReqPool = {maxSockets: 10}; 
var request = require('request'); 

request({url: 'http://localhost:8080/', pool: separateReqPool}, function(e, resp){ 
}); 
+2

這個「sepearateReqPool」似乎適用於我,而且代碼少得多。不知道永遠的代理位(沒有嘗試),但下半年是非常有幫助的。 – jeremy

+0

如果我設置了池,操作系統是否會被接管:false?我的意思是,它仍然會重用保持連接的連接,還是獨佔的應用程序邏輯? – lucaswxp