天天看點

[HTTP] HTTP 中的逾時時間

1. Connection Timeout

對于一般的 HTTP 請求 API 來說,這個 Connection Timeout 代表用戶端最大的等待時長,如果超過了這個時間,那麼就會抛出異常,不會再繼續等待下去。因為有的請求的 API 是阻塞式的(例如 Python 的 Requests 庫),需要終止等待,繼續其他工作。有時候 Connection Timeout 代表的是用戶端的整個等待時間,有時候也會分的細緻一些,這個要看上下文,會分成三個部分:

  • Connection Timeout:用戶端和伺服器建立連接配接的時間,因為 HTTP 底層基于 TCP,是以會有一個連接配接建立的過程,如果超過這個時間,那麼應該會出現這個 Timeout;
  • Write Timeout:用戶端發送資料的時間,例如用戶端要發送一個檔案到伺服器上,用戶端不停的發送資料,如果超過這個時間,就會出現 Write Timeout,不過這個不常用,一般 API 裡也沒有設定這個值的接口;
  • Read Timeout:用戶端等待伺服器響應的時間,這個比較常見,例如伺服器需要處理複雜的業務,處理時間過長,超過這個時間,那麼用戶端會出現 Read Timeout。

可以用 Python 簡單試一下:

先構造一個伺服器,接收 get 請求,收到請求後,挂起 10s,然後再響應;

from http.server import BaseHTTPRequestHandler, HTTPServer
from time import sleep

class handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        sleep(10)
        self.send_header('Content-type','text/html')
        self.end_headers()

        message = "Hello, World!"
        self.wfile.write(bytes(message, "utf8"))

with HTTPServer(('', 8000), handler) as server:
    server.serve_forever()
           

然後發起請求

import requests as re
# timeout 如果不是元組,是一個數值的話,代表用戶端的等待時間
# 或者 (connection timeout, read timeout)
resp = re.get("http://127.0.0.1:8000", timeout=(1,3))
print(resp.text)
           

不出意外,收到了 read timeout,用戶端超過 3s 沒有收到伺服器的回應,抛出了異常。如果我們把 read timeout 從 3 調整到 11,用戶端就可以順利收到消息。

requests.exceptions.ReadTimeout: HTTPConnectionPool(host='127.0.0.1', port=8000): Read timed out. (read timeout=3)
           

2. Request Timeout 408

這個一般是說,伺服器等待太久沒有收到來自用戶端的消息,進而關閉了連接配接,防止伺服器資源被空閑的連接配接所浪費。

繼續閱讀