大家都知道在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了。
文章列表