簡體   English   中英

PHP cURL:CURLOPT_CONNECTTIMEOUT 與 CURLOPT_TIMEOUT

[英]PHP cURL: CURLOPT_CONNECTTIMEOUT vs CURLOPT_TIMEOUT

PHP 有這兩個與超時相關的選項: CURLOPT_CONNECTTIMEOUTCURLOPT_TIMEOUT

PHP網站上的描述有點模糊。 有什么不同?

使用一個真實世界的例子:假設你通過 cURL 發送 GET vars 到 URL 並且你想收到一個 XML 回來, CURLOPT_CONNECTTIMEOUT與連接到服務器所需的最長時間有關,而CURLOPT_TIMEOUT與最大數量有關發送 XML 需要多少時間?

CURLOPT_CONNECTTIMEOUT是與服務器建立連接所允許的最長時間(以秒為單位)。 可以將其設置為0以禁用此限制,但這在生產環境中是不可取的。

CURLOPT_TIMEOUT是限制執行單​​個cURL擴展函數調用的最長時間(以秒為單位)。 請注意,此設置的值應包含CURLOPT_CONNECTTIMEOUT的值。

換句話說,CURLOPT_CONNECTTIMEOUT是CURLOPT_TIMEOUT表示的時間段,因此CURLOPT_TIMEOUT的值應該大於CURLOPT_CONNECTTIMEOUT的值。

來自CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT之間的差異

CURLOPT_CONNECTTIMEOUT 不是 CURLOPT_TIMEOUT表示的時間段

如果CURLOPT_CONNECTTIMEOUT設置為3秒而CURLOPT_TIMEOUT設置為4秒,則執行最多可能需要7秒。

我通過模擬慢速服務器連接(iptables drop)測試了這個。

除了接受的答案

根據源代碼 ,設置是連接的:如果兩者都設置,則使用最嚴格的限制。 但只是在連接階段。

/* if a timeout is set, use the most restrictive one */

  if(data->set.timeout > 0)
    timeout_set |= 1;
  if(duringconnect && (data->set.connecttimeout > 0))
    timeout_set |= 2;

  switch(timeout_set) {
  //...
  case 3:
    if(data->set.timeout < data->set.connecttimeout)
      timeout_ms = data->set.timeout;
    else
      timeout_ms = data->set.connecttimeout;
    break;

源的單元測試

接受的答案是不正確的。 有關正確的文檔,請參閱Everything CURL文檔。

基本上連接時間包括建立http連接的兩個方面:

  • DNS解析
  • 建立tcp連接的時間。

CURLOPT_TIMEOUT或CURLOPT_TIMEOUT_MS選項並未涵蓋這段時間。 這些內容涵蓋了我們開始通過剛剛在連接階段建立的TCP連接談論HTTP之后發生的所有事情。

這種區別會給很多人帶來問題,但它確實允許設置相對較短的連接超時,因為如果服務器完全不可用,為什么要等待呢? 但是,如果服務的預期響應時間難以預測,您仍然可以將請求超時合理地延長。

通常,對於生產設置,CURLOPT_CONNECTION_TIMEOUT應小於5秒,CURLOPT_TIMEOUT應盡可能低(不會導致您定期刪除請求)。

CURLOPT_CONNECTTIMEOUT是僅連接到服務器的時間。

CURLOPT_TIMEOUT是連接的全部時間加上交換數據的時間。

因此,CURLOPT_TIMEOUT總是包含CURLOPT_CONNECTTIMEOUT。

要使用CURLINFO_CONNECT_TIME和CURLINFO_TOTAL_TIME驗證它是否非常簡單。

  • curl_getinfo($ ch,CURLINFO_CONNECT_TIME)獲取信息,curl_setopt($ ch,CURLOPT_CONNECTTIMEOUT,$ yourMaxConnTime)設置要連接的最大值。

  • curl_getinfo($ ch,CURLINFO_TOTAL_TIME)獲取信息,curl_setopt($ ch,CURLOPT_TIMEOUT,$ yourMaxTotTime)設置整個操作的最大值。

當然,$ yourMaxTotTime必須始終高於$ yourMaxConnTime。 所有這些值都是秒。

對於那些爭論CURLOPT_TIMEOUT是否包含CURLOPT_CONNECTTIMEOUT的人; 我會提醒您,libcurl 支持超過 23 種不同的操作系統,包括 DOS。

Inte.net 連接非常復雜(代理、DNS 分辨率、IP 連接、IP 接受、SSH/SSL 握手、通過特定協議(如 HTTP)的實際數據傳輸),libcurl 可能並不總是能夠准確地遵守請求的超時。

經驗法則是您應該設置CURLOPT_TIMEOUT >= CURLOPT_CONNECTTIMEOUT因為這是手冊所說的並且 libcurl 會盡力遵守。 通常具有極高的准確性。

但在某些平台或邊緣情況下,您很容易遇到實際超時為CURLOPT_TIMEOUT + CURLOPT_CONNECTTIMEOUT的情況; 或者哎呀,我什至遇到了所有超時都被忽略的情況,因為對於連接過程中的特定步驟,涉及的操作系統/框架不要求超時值並且不會將控制權返回給 libcurl; 這超出了 libcurl 的控制范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM