微软IIS对http keep-alive的“霸道”处理
大家都知道在IIS中有个HTTP keep-alive设置,见下图:
很多人可能和我们一样,以为这样设置后,IIS会就在发送响应内容时加上这个http header——Connection: keep-alive,见下图:
今天在偶然的情况下突然发现——不是这样的,这是一个让人瞠目结舌的骗局——不知从哪个版本的IIS开始,只要用的是http 1.1协议,IIS坚决不发keep-alive响应头(http 1.0的情况未测试,现在主流浏览器用的都是http 1.1)。
即使你手动在IIS中添加这个响应头也无济于事,Connection: keep-alive根本就不会发给浏览器:
而只要稍改一下Connection的名称,比如把Connection改为Connection1就会在浏览器中出现:
而无论怎么改Connection的值 ,也不会在浏览器中出现。
由此可以推断,IIS在发出响应内容前强制地过滤掉了键名为Connectionhttp的http header。
所以,你没有任何办法可以让IIS输出Connection: keep-alive,除非你能修改IIS的源代码。你说霸不霸道!
微软为什么这么干呢?微软的理由真让人哭笑不得。。。
请看stackoverflow上的一个帖子IIS 7.5: Force Keep Alive header in Response:
I opened a support ticket with Microsoft on this and had my worst suspicions confirmed. IIS 7.5 deliberately prevents the connection:keep-alive header from being returned in the response. Per the HTTP 1.1 RFC, all connections should assume keep alive (a departure from HTTP 1.0). Therefore, the omission of this header is the default and correct (?) behavior. When keep-alives are not desirable, IIS will send the connection:close header.
微软这么做竟然是为了遵守HTTP 1.1的标准,HTTP 1.1假设所有的连接都是keep alive的,所以不再需要keep-alive header。
看了一下HTTP 1.1的规范,也的确是这样:
HTTP/1.0, in its documented form, made no provision for persistent connections. Some HTTP/1.0 implementations, however, use a Keep-Alive header to request that a connection persist.
In recognition of their desirable properties, HTTP/1.1 makes persistent connections the default. HTTP/1.1 clients, servers, and proxies assume that a connection will be kept open after the transmission of a request and its response.
微软按标准办事,也许我们不应该有太多怨言。但是为什么不给用户提供一种选择呢——让用户可以通过设置开启keep-alive header。现在的做法给人的感觉就是两个字——霸道。
另外,我们的站点在不用负载均衡的情况下(阿里云SLB会主动加上keep-alive header),因为IIS不发keep-alive header,会造成大量的[RST,ACK]包。
这说明很多浏览器并没有严格遵守HTTP 1.1的标准(这地方有误,请看更新部分)。浏览器都不遵守,微软你这么积极干吗?该遵守标准时不遵守,不该遵守的时候却死守,而且做法还如此霸道。
Windows那么多问题都没怎么让人受伤,而IIS的一个问题就让人很受伤,还好ASP.NET vNext来了!
【更新】
大量的[RST,ACK]包与我们在IIS设置的keep-alive timeout有关(也就是Connection Time-out,在IIS中这一个设置两个地方用),我们设置的是30秒,而Chrome默认keep-alive的间隔是45秒(每隔45秒发送[TCP Keep-Alive ACK]包)。也是就说在Chrome发出keep-alive包之前,IIS由于发现该连接30秒无活动,所以就[RST, ACK]了。
而Firefox默认keep-alive的间隔是10秒。
Chrome与Firefox都不受是否有keep-alive header的影响,这次错怪IIS了。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· autohue.js:让你的图片和背景融为一体,绝了!
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
2009-06-16 博客园上海俱乐部活动总结(2009-6-13)