環境

$ uname -r
4.4.35-33.55.amzn1.x86_64

$ /usr/local/php-5.6.16/bin/php --version
PHP 5.6.16 (cli) (built: Aug 28 2017 06:35:52)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies

結論

curl のタイムアウト動作に対して、
  • default_socket_timeout は影響確認できず(ini_set)
  • max_execution_time は影響確認できず(set_time_limit)
  • CURLOPT_CONNECTTIMEOUT は作用する(curl_setopt)
  • CURLOPT_TIMEOUT も作用する (curl_setopt)
  • CURLOPT_DNS_CACHE_TIMEOUT は影響確認できず(curl_setopt)
  • デフォルトでは2分強でタイムアウト(カーネル仕様と思われる)

curl_setopt 設定値

CURLOPT_CONNECTTIMEOUT :接続の試行を待ち続ける秒数。0 は永遠に待ち続けることを意味します。
CURLOPT_TIMEOUT:cURL 関数の実行にかけられる時間の最大値。

curl_errno の戻り値

  • 正常時:CURLE_OK (0)
  • カーネル側のタイムアウト:CURLE_COULDNT_CONNECT (7)
  • CURLOPT_CONNECTTIMEOUT / CURLOPT_TIMEOUT:CURLE_OPERATION_TIMEDOUT (28)

カーネル側のタイムアウト動作

$ time /usr/local/php-5.6.16/bin/php curl.php
real    2m7.345s
user    0m0.000s
sys     0m0.012s

$ cat /proc/sys/net/ipv4/tcp_syn_retries
6

参考リンク

curl の戻り値
https://curl.haxx.se/libcurl/c/libcurl-errors.html curl実行中に応答が無くなる現象
https://ngyuki.hatenablog.com/entry/2019/09/21/191552 curlのデフォルト値等

https://www.it-swarm.dev/ja/php/php%EF%BC%9A%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%AEcurl%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88%E5%80%A4/1067580731/

https://www.it-swarm.dev/ja/php/php%E3%81%A7%E3%81%AEcurl%E3%81%AE%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A/968216261/

https://stackoverflow.com/questions/10308915/php-default-curl-timeout-value TCPタイムアウト
https://qiita.com/tukiyo3/items/e66393cf5fd0ede8b3b4

ソースコード

<?php

// default_socket_timeout は、本コードでのタイムアウト動作には影響しない
$socket_timeout = ini_get('default_socket_timeout');
print_r("socket_timeout: $socket_timeout \n"); // -> 60

ini_set('default_socket_timeout', 10);

// max_execution_time は、本コードでのタイムアウト動作には影響しない
$max_execution_time = ini_get('max_execution_time'); // timeout in seconds
print_r("max_execution_time: $max_execution_time \n"); // -> 0

set_time_limit(5);

$max_execution_time = ini_get('max_execution_time');
print_r("max_execution_time: $max_execution_time \n"); // -> 5

$url = "https://www.google.com"; // 正常実行
//$url = "8.8.8.8"; // for connect timeout test
//$url = "http://httpbin.org/delay/10"; // for timeout test

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

// デフォルト5分のようだが、カーネルプロトコルスタックのTCP制御で2分強でタイムアウトする
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
//curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 3500);

// デフォルトは、無期限
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
//curl_setopt($ch, CURLOPT_TIMEOUT_MS, 10000);

curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 3); // 本コードでのタイムアウト動作には影響しない

$str = curl_exec($ch);
$errno = curl_errno($ch);

curl_close($ch);

if ($errno !== CURLE_OK) {
    print_r("errno: $errno \n");
    // CURLE_COULDNT_CONNECT (7) -> カーネル側のタイムアウト
    // CURLE_OPERATION_TIMEDOUT (28) -> CURLOPT_CONNECTTIMEOUT or CURLOPT_TIMEOUT
    return false;
}

if (!$str) {
    print_r("error");
    return false;
}

print_r("success");
return true;

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください