Node.js http.エージェントが真のkeep-Aliveエージェントを実現
5180 ワード
一、Kepp-Aliveの使用状況
1、サーバーのメモリが十分な場合、KeepAlive=OnかOffかはシステムの性能にあまり影響しません.
2、サーバー上の静的Webページ(Html、ピクチャ、Css、Js)が多い場合は、KeepAliveを開くことをお勧めします.
3、サーバーがダイナミックな要求が多い場合(データベース接続のため、ファイルシステムへのアクセスが多い)、KeepAliveがオフになると、一定のメモリが節約され、節約したメモリはファイルシステムのCache(vmstatコマンドのcacheの列)として、I/O圧力を下げることができます.
PS:KeepAlive=Onの場合、KeepAliveTimeOutの設定も実は問題で、設定が短すぎると、Apacheが頻繁に接続を確立し、Cpuに圧力をかけ、設定が長すぎると、システムに無駄なHttp接続が蓄積され、大量のメモリが消費され、具体的な設定が少なく、絶えず調整することができ、あなたのウェブサイトの閲覧とサーバーの構成によって異なります.
二、ブラウザによるKeep-Aliveの同時発生数及びドメイン名のオーバーヘッド
HTTP/1.0にとって、ブラウザのデフォルト最大同時接続数がHTTP/1.1より多いメリットを十分に利用でき、新しいドメイン名のオーバーヘッドを増やさずにより高い並列ダウンロードを実現できます.ドメイン名解釈のオーバーヘッドを削減(注:IE 6,7 HTTP/1.0では最大同時接続数が4、HTTP/1.1では最大同時接続数が2、IE 8では6、Firefox 2ではHTTP/1.0では最大同時接続数が2、HTTP/1.1では最大同時接続数が8、firefox 3ではデフォルトが6)10年7月のGoogleインデックスの42億ページの統計報告によると、各ページには29.39の図が含まれているスライス、7.09外部スクリプト、3.22外部CSSスタイルシート、Keep-Aliveを設定し、Keep-Alive TimeOutというパラメータを合理的に制御すれば、接続のオーバーヘッドを大幅に節約し、対応する速度を向上させることができます.設置がうまくいかなければ,大同時の場合は小さく,大量の接続を維持するためにサーバ資源が枯渇するが,現在国内の大部分のユーザが使用しているのはIE 6,7の場合である.
三、Nodeを使う.jsのhttp.エージェントは本物のKeep-Aliveエージェントを開発しました
使用方法:
1、サーバーのメモリが十分な場合、KeepAlive=OnかOffかはシステムの性能にあまり影響しません.
2、サーバー上の静的Webページ(Html、ピクチャ、Css、Js)が多い場合は、KeepAliveを開くことをお勧めします.
3、サーバーがダイナミックな要求が多い場合(データベース接続のため、ファイルシステムへのアクセスが多い)、KeepAliveがオフになると、一定のメモリが節約され、節約したメモリはファイルシステムのCache(vmstatコマンドのcacheの列)として、I/O圧力を下げることができます.
PS:KeepAlive=Onの場合、KeepAliveTimeOutの設定も実は問題で、設定が短すぎると、Apacheが頻繁に接続を確立し、Cpuに圧力をかけ、設定が長すぎると、システムに無駄なHttp接続が蓄積され、大量のメモリが消費され、具体的な設定が少なく、絶えず調整することができ、あなたのウェブサイトの閲覧とサーバーの構成によって異なります.
二、ブラウザによるKeep-Aliveの同時発生数及びドメイン名のオーバーヘッド
HTTP/1.0にとって、ブラウザのデフォルト最大同時接続数がHTTP/1.1より多いメリットを十分に利用でき、新しいドメイン名のオーバーヘッドを増やさずにより高い並列ダウンロードを実現できます.ドメイン名解釈のオーバーヘッドを削減(注:IE 6,7 HTTP/1.0では最大同時接続数が4、HTTP/1.1では最大同時接続数が2、IE 8では6、Firefox 2ではHTTP/1.0では最大同時接続数が2、HTTP/1.1では最大同時接続数が8、firefox 3ではデフォルトが6)10年7月のGoogleインデックスの42億ページの統計報告によると、各ページには29.39の図が含まれているスライス、7.09外部スクリプト、3.22外部CSSスタイルシート、Keep-Aliveを設定し、Keep-Alive TimeOutというパラメータを合理的に制御すれば、接続のオーバーヘッドを大幅に節約し、対応する速度を向上させることができます.設置がうまくいかなければ,大同時の場合は小さく,大量の接続を維持するためにサーバ資源が枯渇するが,現在国内の大部分のユーザが使用しているのはIE 6,7の場合である.
三、Nodeを使う.jsのhttp.エージェントは本物のKeep-Aliveエージェントを開発しました
/**
* Created by Administrator on 14-4-30.
*/
var http = require('http');
var EventEmitter = require('evnets').EventEmitter;
var net = require('net');
var util = require('util');
var Agent = function(optinos)
{
var self = this;
//
self.options = options || {};
// hostname
self.requests = {};
// socket
self.sockets = {};
// socket
self.unusedSockets = {};
// socket
self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets;
self.on('free',function(socket,host,port){
var hostname = host + ':' + port;
//
if(self.requests[hostname] && self.requests[hostname].length)
{
self.requests[hostname].shift().onSocket(socket);
}
else
{
// socket
if(!self.unusedSockets[hostname])
{
self.unusedSockets[hostname] = [];
}
self.unusedSockets[hostname].push(socket);
}
});
self.createConnection = net.createConnection;
};
util.inherits(Agent,EventEmitter);
Agent.defaultMaxSockets = 10;
Agent.prototype.defaultPort = 80;
Agent.prototype.addRequest = function(req,host,port)
{
var hostname = host + ':' + port;
if(this.unusedSockets[hostname] && this.unusedSockets[hostname].length)
{
req.onSocket(this.unusedSockets[hostname].shift());
return;
}
if(!this.sockets[hostname])
{
this.sockets[hostname] = [];
}
if(this.sockets[hostname].length < this.maxSockets)
{
req.onSocket(this.createSocket(hostname,host,port));
}
else
{
if(!this.requests[hostname])
{
this.requests[hostname] = [];
}
this.requests[hostname].push(req);
}
};
Agent.prototype.createSocket = function(name, host, port) {
var self = this;
var s = self.createConnection(port, host, self.options);
if (!self.sockets[name]) {
self.sockets[name] = [];
}
this.sockets[name].push(s);
var onFree = function() {
self.emit('free', s, host, port);
}
s.on('free', onFree);
var onClose = function(err) {
// socket , socket, , socket
self.removeSocket(s, name, host, port);
}
s.on('close', onClose);
var onRemove = function() {
// We need this function for cases like HTTP "upgrade"
// (defined by WebSockets) where we need to remove a socket from the pool
// because it'll be locked up indefinitely
self.removeSocket(s, name, host, port);
s.removeListener('close', onClose);
s.removeListener('free', onFree);
s.removeListener('agentRemove', onRemove);
}
s.on('agentRemove', onRemove);
return s;
};
Agent.prototype.removeSocket = function(s, name, host, port) {
if (this.sockets[name]) {
var index = this.sockets[name].indexOf(s);
if (index !== -1) {
this.sockets[name].splice(index, 1);
}
} else if (this.sockets[name] && this.sockets[name].length === 0) {
delete this.sockets[name];
delete this.requests[name];
}
if (this.requests[name] && this.requests[name].length) {
// If we have pending requests and a socket gets closed a new one
// needs to be created to take over in the pool for the one that closed.
this.createSocket(name, host, port).emit('free');
}
};
使用方法:
var http = require('http');
var keepAliveAgent = require('./agent.js');
var agent = new keepAliveAgent({ maxSockets: 100 });
// Optionally define more parallel sockets
var options = {
agent: agent,
hostname: 'example.com',
path: '/path'};
// do get
http.get(options);
// do request
http.request(options,function(){});