一、當你的Server內存充足時,KeepAlive =On仍是Off對系統性能影響不大。css
二、當你的Server上靜態網頁(Html、圖片、Css、Js)居多時,建議打開KeepAlive 。數據庫
三、當你的Server多爲動態請求(由於鏈接數據庫,對文件系統訪問較多),KeepAlive 關掉,會節省必定的內存,節省的內存正好能夠做爲文件系統的Cache(vmstat命令中cache一列),下降I/O壓力。 瀏覽器
PS:當KeepAlive =On時,KeepAliveTimeOut的設置其實也是一個問題,設置的太短,會致使Apache 頻繁創建鏈接,給Cpu形成壓力,設置的過長,系統中就會堆積無用的Http鏈接,消耗掉大量內存,具體設置多少,能夠進行不斷的調節,因你的網站瀏覽和服務器配置 而異。服務器
對於HTTP/1.0來講能夠充分利用瀏覽器默認最大併發鏈接數比HTTP/1.1多的好 處,實現不增長新域名的開銷而更高的並行下載,減小域名解釋的開銷(注:IE 6,7在HTTP/1.0中默認最大併發鏈接數爲4,在HTTP/1.1中默認最大併發鏈接數爲2,IE8都爲6,Firefox2在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這個參數能夠大量的節約鏈接的開銷,提升相應速度。若是設置很差,在大併發的狀況小,因維持大量鏈接而使服務器資源耗盡,而對於目前國內大 部分的用戶使用的仍是IE6,7的狀況併發
/** * 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'); } };
如何使用:socket
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(){});