1. 程式人生 > >005_關於HTTP協議中的保持連接

005_關於HTTP協議中的保持連接

註意 o-c 一段 apach user 一段時間 enc 關閉連接 1.5

緣起

中午在群裏討論,用ab測試 一臺只提供靜態文件服務, 不與其他任何系統交互的時候,為什麽也會產生大量的TIME WAIT狀態的。

首先,我們可以簡單的理解,在TCP連接的兩端,誰主動斷開連接(先發送FIN包),誰進入TIME WAIT,誰被動斷開連接(後發送FIN包),誰進入CLOSE WAIT狀態。

那麽,由此可以推斷,在這個場景中,server是主動斷開連接的一方,那麽server為什麽會主動斷開呢, 這就涉及到HTTP裏關於keepalive的內容了。

我們常常聽說keepalive能提高webserver的性能, 但是為什麽呢? 這裏暫且不解釋,說完下面的內容,就清楚了。

分析

在HTTP協議中, 除了需要服務器支持並打開keepalive之外, 還有一個重要的請求頭Connection

需要註意。

我們來看下面一個請求:

GET /? HTTP/1.1
Accept: */*
Cache-Control: no-cache
Connection: close
Host: 127.0.0.1
User-Agent: Apache-HttpClient/4.3.2 (java 1.5)
Accept-Encoding: gzip,deflate

這是我通過Idea 的REST Client 插件發送的一個請求, 我們看到 Connection頭的值是close,抓包看一下請求過程技術分享

可以看到, 在server響應完成後, 發送了FIN 包, 主動斷開連接, 這很好理解。

在來看一個請求:

GET /? HTTP/1.1
Accept: */*
Cache-Control: no-cache
Connection: keep-alive
Keep-Alive: 5
Host: 127.0.0.1
User-Agent: Apache-HttpClient/4.3.2 (java 1.5)
Accept-Encoding: gzip,deflate

可以看到, 這個請求裏, Connection的值變成了keep-alive, 並且多了一個Keep-Alive頭,值為5。再抓包看看這次請求:

技術分享

可以看到, server在響應完成後,並沒有發送FIN包關閉連接, 而是一段時間後,客戶端發送FIN包,關閉連接, 如果你看第二列, time會發現,正好是大約5秒後,客戶端發送了FIN包, 這個數值正好是 Keep-Alive頭的值。事實上,Keep-Alive頭的語義就是客戶端保持連接多少秒。

以上的測試, server配的keepalive都是65s, 我們來把它0, 再來測試一遍看看。

客戶端Connection頭為close的情況:

技術分享

客戶端Connection

keep-alive, Keep-Alive5的情況

技術分享

可以看到,server主動斷開連接。

最後一個場景, server配置keepalive為3, client Connectionkeep-alive, Keep-Alive5的情況

技術分享

可以看到,請求結束大約3秒後(主要時間戳),server發送FIN主動斷開連接。

結論

說了這麽多,是時候總結一下了,關於keepalive主要有一下幾點:

  • Connection 頭控制客戶端是否開啟, close 不開啟, keep-alive開啟
  • Keep-Alive頭控制客戶端保持連接的時間
  • 在開啟keepalive的時候, 誰先到保持連接的時間,誰先發FIN包,主動關閉連接。

005_關於HTTP協議中的保持連接