HTTP的持久连接对Web服务性能的影响

简介:

       我们的 Web 页面通常有很多对像(Object)组成。如:jss 样式表、图片、scripts、文档等。所以用户浏览一个网页文件时候,要向 Web 服务器发送多次请求(要从服务器上获取一个Object就要向服务器发送一个请求),浏览器根据 jss 样式表把从服务器获取的这些html页面对象合成一个完整的html页面展示给用户。
        最早我们的浏览器是单线程的,意味着一次只能向浏览器发送一个Object请求,等到该Object传输完成了,再向服务发送第二个Object的请求。我们把它称为串行事务处理。串行事务处理,使得我们的连接时延会叠加,用户的体验效果差。如,页面有多幅图片,页面正在加载一幅图片时,页面上其它地方都没有动静,也会让人门觉得很慢。后来出现了多线程的浏览器,当用户点击打开一个页面时,会同时向服务器同时发起多个用户请求(也就是并行处理方式),减少了连接时延叠加,同时加速了一个web页面对象的加载速度,让用户有更好的体验效果。
        虽然采用多线程的浏览器加速了页面的加载速度,但是如果我们只对连接进行简单的管理(如不使用 keep alive),浏览器每获得一个Web对像都要使用一个新的TCP连接。
意思是说我们加载的html页面有多少个页面对象,浏览器与服务器要建立多少条TCP连接。大家都知道使用TCP传输数据之前,要先经过三次握手,三次握手成功以后,双方才能够进行数据的传输。
所以说,我们使用TCP/IP进行数据网络传输必定会造成延迟的。双方完成数据的传输以后还要经过TCP的四次断开的过程。一个TCP的连接要经过:建立连接 、传输数据、拆除连接。

        TCP的建立连接和拆除连接是很费时的,有时候甚至比数据传输的时间还长。所以,虽然浏览器采用了并发处理方式,加速了页面的加载速度。但是请求一个页面对像就需要与服务器建立一条TCP连接。如果用户浏览的页面文件有1000个object的话,从服务器请求数据到展示给用户,

        最基本延迟时间 = 1000*(平均每个TCP连接建立时间 + 平均每个TCP连接拆除时间)。
随着我们的页面对像的增加,这个延迟时间是不断增长的。客户端每请求一个object,就要与服务器建立一条TCP连接,服务器每维护一条TCP连接是要消耗一定的资源(如内存)。所以,也加速了服务器的负担。对服务器的并发用户数也造成很大影响。所以后来 HTTP/1.1 使用了重用TCP连接功能来消除连接及关闭时延。允许HTTP设备在事务处理结束之后将TCP连接保持在打开状态,
以便为后续的HTTP请求重用现存的TCP连接。在事务处理结束之后仍然保持在打开状态的TCP连接被称为持久连接。也称为 TCP 重用。


      是如何重用TCP连接的呢?
      假如,浏览的网页文件有400个object.我们的浏览器是4线程的,浏览器会并行向 Web 服务器发送4个 TCP连接请求。当这4个TCP请求与服务器建立连接完成数据传输以后,并不是
把它拆除掉。浏览器与web服务器协定使用 keep-alive 功能时。HTTP设备就会在事务处理结束之后将该4条TCP连接保持在打开状态。浏览器就使用这4条TCP连接完成后续的396个object的数据转输。
        持久连接降低了时延和连接建立的开销,将连接保持在已调谐状态,而且减少了打开连接的潜在数量。但是,管理 持久连接时要特别小心,不然就会累积出大量的空闲连接,耗费客户端和服务器上的资源。下面是 Apache web 服务器管理持久连接的一些配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@node2 ~] # vim /etc/httpd/extra/httpd-default.conf
...
#KeepAlive On
KeepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
# 保持连接允许传输的最大请求数
MaxKeepAliveRequests 100
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
# 在同一个客户端的连接,等待下一个请求的超时时间
KeepAliveTimeout 5
...

说明:

这些就是 Keep-Alive选项。
注意,Keep-Alive 首部只是请求将连接保持在活跃状态。发出 keep-alive 请求之后,客户端和服务器并不一定会同意进行 keep-alive 会话。
它们可以在任意时刻关半空闲的 keep-alive 连接,并可随意限制 keep-alive 连接所处理事务的数量。

下面来看看,客户端与服务器怎样商量它们是否使用HTTP协议的持久连接功能的呢?
实现 HTTP/1.0 keep-alive 连接的客户端可以通过包含 Connection: Keep-Alive 首部请求将一条连接保持在打开状态。


通过 Google Chrome 浏览器的开发者工具来查看,访问 http://192.168.203.99/index.html 的请求头信息。

1
2
3
4
5
6
7
8
9
10
Request Header
Accept:text /html ,application /xhtml +xml,application /xml ;q=0.9,image /webp ,*/*;q=0.8
Accept-Encoding: gzip ,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:no-cache
Connection:keep-alive     -----> 请求将一条连接保持在打开状态。
Cookie:2c407_ol_offset=97; 2c407_ipstate=1402781651; 2c407_jobpop=0; 2c407_winduser=BD4OUFQKBQkLVgReBgsAAFsDVlMKB1MGUQ4LAwcFUlgBBms; 2c407_ck_info=%2F%09; 2c407_lastpos=index; 2c407_lastvisit=49%091402713397%09%2Findex.php
Host:192.168.203.99
Pragma:no-cache
User-Agent:Mozilla /5 .0 (Windows NT 6.2; WOW64) AppleWebKit /537 .36 (KHTML, like Gecko) Chrome /34 .0.1847.137 Safari /537 .36

通过工具 crul 获得的响应头信息。

1
2
3
4
5
6
7
8
9
[root@node2 ~] # curl -I http://192.168.203.99/index.html
HTTP /1 .1 200 OK
Server: nginx /1 .0.11
Date: Sat, 14 Jun 2014 09:17:15 GMT
Content-Type: text /html
Content-Length: 151
Last-Modified: Thu, 01 May 2014 04:21:03 GMT
Connection: keep-alive
Accept-Ranges: bytes

说明:
    如果服务器愿意为下一条请求将连接保持在打开状态(意思是说下一次请求数据时,可以通过该TCP连接传输数据,不需要建立新的TCP连接了),
    就在响应中包含相同的首部 Connection: keep-alive。
    如果响应中没有 Connection: keep-alive 首部,客户端就认为服务器不支持 keep-alive,会在发回响应报文之后关闭连接@。
    从上在请求首部和响应首部分析,我们使用了HTTP 持久连接的功能。

总结:
   Keep-Alive 连接的限制和规则:
   1、在 HTTP/1.0 中,keep-alive 并不是默认使用的,客户端必须发送一个 Connection: Keep-Alive

         请求首部来激活 keep-alive 连接。
   2、Connection: Keep-Alive 首部必须随所有希望保持持久连接的报文一起发送。如果客户端没有发

         送 Connection: Keep-Alive 首部,服务器就会在那条请求之后关闭连接。
   3、客户端探明响应中没有 Connection: Keep-Alive 响应首部,就可以知道服务器发出响应之后是否

          会关闭连接了。
   4、为了避免出现大量的空闲的TCP连接,要定义持久连接的超时时间 timeout.  限制操持连接的TCP

         连接最多能完成多少个事务 MaxKeepAliveRequests



     本文转自成长的小虫 51CTO博客,原文链接:http://blog.51cto.com/9528du/1426695,如需转载请自行联系原作者



相关文章
|
10月前
|
开发框架 监控 安全
Windows Defender 导致 Web IIS 服务异常停止排查
某日凌晨IIS服务异常停止,经查为Windows Defender安全补丁KB2267602触发引擎更新,导致系统资源波动,进而引发应用池回收。确认非人为操作,系统无重启。通过分析日志与监控,定位原因为Defender更新后扫描加重负载。解决方案:将IIS及.NET相关路径添加至Defender排除列表,避免业务影响。
1028 116
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
604 61
|
XML JSON 数据安全/隐私保护
Web服务
【10月更文挑战第18天】Web服务
506 9
|
前端开发 JavaScript 安全
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第27天】本文介绍了HTTP/2和HTTPS在前端性能调优中的应用。通过多路复用、服务器推送和头部压缩等特性,HTTP/2显著提升了Web性能。同时,HTTPS确保了数据传输的安全性。文章提供了示例代码,展示了如何使用Node.js创建一个HTTP/2服务器。
522 3
|
应用服务中间件 网络安全 数据安全/隐私保护
网关服务器配置指南:实现自动DHCP地址分配、HTTP服务和SSH无密码登录。
哇哈哈,道具都准备好了,咱们的魔术秀就要开始了。现在,你的网关服务器已经魔法满满,自动分配IP,提供网页服务,SSH登录如入无人之境。而整个世界,只会知道效果,不会知道是你在幕后操控一切。这就是真正的数字世界魔法师,随手拈来,手到擒来。
634 14
|
中间件 Go
Golang | Gin:net/http与Gin启动web服务的简单比较
总的来说,`net/http`和 `Gin`都是优秀的库,它们各有优缺点。你应该根据你的需求和经验来选择最适合你的工具。希望这个比较可以帮助你做出决策。
729 35
|
开发框架 安全 前端开发
Go Web开发框架实践:模板渲染与静态资源服务
Gin 是一个功能强大的 Go Web 框架,不仅适用于构建 API 服务,还支持 HTML 模板渲染和静态资源托管。它可以帮助开发者快速搭建中小型网站,并提供灵活的模板语法、自定义函数、静态文件映射等功能,同时兼容 Go 的 html/template 引擎,具备高效且安全的页面渲染能力。
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
数据采集 Web App开发 API
FastAPI与Selenium:打造高效的Web数据抓取服务 —— 采集Pixabay中的图片及相关信息
本文介绍了如何使用FastAPI和Selenium搭建RESTful接口,访问免版权图片网站Pixabay并采集图片及其描述信息。通过配置代理IP、User-Agent和Cookie,提高爬虫的稳定性和防封禁能力。环境依赖包括FastAPI、Uvicorn和Selenium等库。代码示例展示了完整的实现过程,涵盖代理设置、浏览器模拟及数据提取,并提供了详细的中文注释。适用于需要高效、稳定的Web数据抓取服务的开发者。
1091 15
FastAPI与Selenium:打造高效的Web数据抓取服务 —— 采集Pixabay中的图片及相关信息
|
关系型数据库 MySQL PHP
源码编译安装LAMP(HTTP服务,MYSQL ,PHP,以及bbs论坛)
通过以上步骤,你可以成功地在一台Linux服务器上从源码编译并安装LAMP环境,并配置一个BBS论坛(Discuz!)。这些步骤涵盖了从安装依赖、下载源代码、配置编译到安装完成的所有细节。每个命令的解释确保了过程的透明度,使即使是非专业人士也能够理解整个流程。
548 18