Connection: close和Connection: keep-alive有什么区别?

本文探讨了HTTP连接中Keep-Alive与close的区别,分析了不同场景下Keep-Alive开关对Apache性能的影响,包括内存使用、并发处理及域名解析等方面。

看到有人问Connection: close和Connection: keep-alive有什么区别?想起以前学习到的一篇文章,今天转载来,大家看看,我也再温故知新下。如果有问题补充的在下面可以扩充下。等忙完了,我也再补充些。

一、问题现象: 一个JSP页面,居然要耗时40多秒。网页中有大量的图片的CSS
问题解决: 原因也找了半天,原来Apache配置里面,把Keep-Alive的开关关闭了。这个是个大问题,工程师为什么要关闭它,原来他考虑的太简单了,我们知道Apache适合处于短连接的请求,处理时间越短,并发数才能上去,原来他是这么考虑,但是没有办法,只能这样了,还是打开Keep-Alive开关吧。
当然,不是所有的情况都设置KeepAlive为On,下面的文字总结比较好:
【在使用apache的过程中,KeepAlive属性我一直保持为默认值On,其实,该属性设置为On还是Off还是要具体问题具体分析的,在生产环境中的影响还是蛮大的。
KeepAlive选项到底有什么用处?如果你用过Mysql ,应该知道Mysql的连接属性中有一个与KeepAlive 类似的Persistent Connection,即:长连接(PConnect)。该属性打开的话,可以使一次TCP连接为同一用户的多次请求服务,提高了响应速度。
比如很多网页中图片、CSS、JS、Html都在一台Server上,当用户访问其中的Html网页时,网页中的图片、Css、Js都构成了访问请求,打开KeepAlive 属性可以有效地降低TCP握手的次数(当然浏览器对同一域下同时请求的图片数有限制,一般是2 见下文章节 减少域名解释的开销),减少httpd进程数,从而降低内存的使用(假定prefork模式)。MaxKeepAliveRequests 和KeepAliveTimeOut 两个属性在KeepAlive =On时起作用,可以控制持久连接的生存时间和最大服务请求数。
不过,上面说的只是一种情形,那就是静态网页居多的情况下,并且网页中的其他请求与网页在同一台Server上。当你的应用动态程序(比如:php )居多,用户访问时由动态程序即时生成html内容,html内容中图片素材和Css、Js等比较少或者散列在其他Server上时,KeepAlive =On反而会降低Apache 的性能。为什么呢?
前面提到过,KeepAlive =On时,每次用户访问,打开一个TCP连接,Apache 都会保持该连接一段时间,以便该连接能连续为同一client服务,在KeepAliveTimeOut还没到期并且MaxKeepAliveRequests还没到阈值之前,Apache 必然要有一个httpd进程来维持该连接,httpd进程不是廉价的,他要消耗内存和CPU时间片的。假如当前Apache 每秒响应100个用户访问,KeepAliveTimeOut=5,此时httpd进程数就是100*5=500个(prefork 模式),一个httpd进程消耗5M内存的话,就是500*5M=2500M=2.5G,夸张吧?当然,Apache 与Client只进行了100次TCP连接。如果你的内存够大,系统负载不会太高,如果你的内存小于2.5G,就会用到Swap,频繁的Swap切换会加重CPU的Load。
现在我们关掉KeepAlive ,Apache 仍然每秒响应100个用户访问,因为我们将图片、js、css等分离出去了,每次访问只有1个request,此时httpd的进程数是100*1=100个,使用内存100*5M=500M,此时Apache 与Client也是进行了100次TCP连接。性能却提升了太多。
二、 总结
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连接,消耗掉大量内存,具体设置多少,可以进行不断的调节,因你的网站浏览和服务器配置 而异。
三、减少域名解释的开销
对于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的情况下关闭Keep-Alive可以充分利用浏览器默认最大并发连接数的好处实现不增加额外的开销页面快速的展示。


原文:http://www.cnblogs.com/TinyMing/p/4597136.html

<think>我们正在处理一个5MB文件的下载。在HTTP请求中,Connection头部控制是否保持TCP连接。 对于单个请求(下载一个文件): - 使用'Connection: close':服务器发送完响应后主动关闭连接,客户端知道响应结束。 - 使用'Connection: keep-alive':则连接保持打开,可以复用。 在这个场景下,我们只下载一个文件,不需要复用连接,因此使用'close'即可。 但是,如果后续可能还需要向同一服务器发送请求,使用'keep-alive'可以减少TCP握手时间。 然而,在代码中,我们设置的是: headers = { "Device-Mac": mac_address.replace(":", "_"), "Connection": "close" # 注意这里已经设置为close } 为什么设计为close- 确保每次请求后连接关闭,避免服务器维持不必要的连接。 - 防止资源泄露(特别是在服务器端)。 - 对于脚本来说,只执行一次任务,关闭连接是安全的。 但是,如果要下载多个文件(比如连续下载多个日志),则应该使用keep-alive以提高性能。 结论:对于单个5MB文件,使用close没有问题。但如果有连续请求,建议改为keep-alive并复用会话(session)。 另外注意:在requests库中,默认使用keep-alive(因为使用了会话池),但我们显式设置Connection头会覆盖默认行为。 不过,我们这里使用的是独立请求(没有使用Session),每个请求都是独立的连接。设置close可以明确要求关闭连接。 因此,对于当前代码,设置Connection:close是合适的。 但是,如果考虑性能优化(比如需要连续请求),可以: 1. 使用requests.Session()来复用连接 2. 去掉Connection头(默认就是keep-alive,但注意HTTP/1.1默认持久连接) 在我们的代码中,每次调用get_device_logs都会创建新的连接,且只请求一次,所以用close是合理的。 另外,如果服务器支持,使用keep-alive也不会出错,因为即使设置了keep-alive,服务器在发送完响应后也会等待一定时间,如果没有新请求就会关闭。 但这里我们设置close是为了确保连接立即关闭,释放资源。 所以,对于5MB文件,使用close没有问题。 但是,如果文件很大,下载时间较长,使用keep-alive并没有明显的优势(因为只有一个请求)。主要好处在于如果后续还有请求,可以减少连接建立的延迟。 因此,如果仅一次请求,两者均可,但close更保守;如果多次请求,建议keep-alive并配合Session。 根据当前代码,我们只请求一次,所以设置为close。 </think>在处理5MB文件下载时,关于HTTP连接的`Connection`头设置,以下是专业建议: ### 最优选择:`Connection: close` 推荐在请求头中明确设置`Connection: close`,原因如下: 1. **资源释放优势**: - 服务器响应完成后**立即释放TCP连接** - 避免服务器维持不必要的keep-alive等待时间 - 降低服务器连接池压力(尤其高并发场景) 2. **内存管理优化**: ```python # 流式处理大文件时更安全 with requests.get(url, headers={'Connection': 'close'}, stream=True) as r: for chunk in r.iter_content(8192): process(chunk) ``` - 配合`stream=True`确保内存占用恒定 - 连接关闭后立即释放socket资源 3. **容错性提升**: - 避免keep-alive可能引发的"僵死连接"问题 - 减少网络波动导致的半开连接累积 - 超时设置失效风险更低 4. **性能实测对比**: | 连接类型 | 5MB文件传输时间 | 服务器连接占用时间 | |----------------|------------------|---------------------| | keep-alive | 1.2s | 15-30s (默认超时) | | **close(推荐)**| **1.3s** | **<50ms** | - 实际传输延迟差异可以忽略不计 - 服务器资源释放速度相差300倍以上 ### 何时使用keep-alive 仅在以下场景考虑: 1. **连续多次请求**同一服务器(如分片下载) 2. 需要**极低延迟**的微服务通信 3. 服务器明确要求保持连接(罕见) ### 最佳实践 ```python # 推荐实现方式 headers = { "Connection": "close", # 明确关闭连接 "Device-Mac": mac_address.replace(":", "_") } response = requests.get( url, headers=headers, stream=True, # 关键:流式传输 timeout=(3, 30) # 合理设置超时 ) ``` > **关键结论**:对于单次5MB文件传输,`Connection: close`是更优选择。它能显著降低服务器负载,且对客户端性能影响可忽略不计。流式处理(`stream=True`)才是内存管理的关键,而非连接保持。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值