博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Node.js http.Agent实现真正的keep-Alive代理
阅读量:5749 次
发布时间:2019-06-18

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

hot3.png

一、 Kepp-Alive使用情况

1、当你的Server内存充足时,KeepAlive =On还是Off对系统性能影响不大。

2、当你的Server上静态网页(Html、图片、Css、Js)居多时,建议打开KeepAlive 。

3、当你的Server多为动态请求(因为连接数据库,对文件系统访问较多),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,IE8都为6,Firefox2在HTTP/1.0中 默认最大并发连接数为2 在HTTP/1.1中默认最大并发连接数为8,firefox 3默认都是6),根据10年7月Google索引的42亿个网页的统计报告,每张网页里包含29.39个图片,7.09个外部脚本,3.22个外部 样式表,如果设置了Keep-Alive并且合理控制Keep-Alive TimeOut这个参数可以大量的节约连接的开销,提高相应速度。如果设置不好,在大并发的情况小,因维持大量连接而使服务器资源耗尽,而对于目前国内大 部分的用户使用的还是IE6,7的情况

三、使用Node.js的http.Agent开发一个真正的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 gethttp.get(options);// do requesthttp.request(options,function(){});

转载于:https://my.oschina.net/antianlu/blog/261105

你可能感兴趣的文章
关于HTTP的笔记
查看>>
进程调度(四)
查看>>
黄了!利欧股份终止23亿天价收购自媒体
查看>>
(C#)Windows Shell 外壳编程系列7 - ContextMenu 注册文件右键菜单
查看>>
_RecordsetPtr异常捕获
查看>>
函数计算搭建 Serverless Web 应用(三)- 三分钟搭建 Web 应用
查看>>
OS X编译安装php
查看>>
swift 基础笔记五(集合)
查看>>
html使用a标签不通过后台实现直接下载
查看>>
读代码是好的学习方式么
查看>>
阿里云产品总监何云飞:云平台是企业数字化转型的核心驱动力
查看>>
rabbitmq_学习_01_rabbitmq安装
查看>>
仿大街网-堆栈式卡片布局-SwipeCardLayout
查看>>
RevealView
查看>>
【新闻】微信小程序开发工具升级到版本 0.10.102700
查看>>
MaxCompute Tunnel上传典型问题场景
查看>>
Chrome 72 丢弃 HPKP,不再支持TLS1.0和TLS1.1!
查看>>
界面无小事(四):来写个滚动选择器吧!
查看>>
windows7上使用docker容器
查看>>
提交工单和知道提问的区别
查看>>