動機
http://blog.mach3.jp/2010/12/21/use-curl-for-filegetcontents.html
パフォーマンスアップ!
http://www.psi-net.co.jp/blog/?p=1123
タイムアウトを正確に設定する!
GET
変更前
$url = 'https://api.cognitive.microsoft.com/<サービス>';
$header = 'Ocp-Apim-Subscription-Key: ' . $subscriptionKey;
$context = stream_context_create(array(
'http' => array(
'request_fulluri' => true,
'header' => $header,
'timeout' => 1
)
));
$response = file_get_contents($url, 0, $context);
変更後
$url = 'https://api.cognitive.microsoft.com/<サービス>';
$header = 'Ocp-Apim-Subscription-Key: ' . $subscriptionKey;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
$response = curl_exec($ch);
curl_close($ch);
ポイントは・・・Azureの管理画面での平均レスポンスタイムが400msだから1秒でいいかと設定したらタイムアウト発生しまくりで2秒が必須だったというあたりくらい。
最初認証OKなのにデータが返って無くて戸惑いました。
年末以降サーバーエラーとか遅延時間が増えたりとか60秒以上反応返ってこないとか不安定なんですよね・・・(今回の変更のトリガー)
高々数KBのデータ受信に1秒以上かかるというのはAzureサービスの回線が細いのかな?
POST
変更前
$postdata = array(
'hoge' => $hoge,
'moge' => $moge
);
$postjson = json_encode($postdata);
$header = array(
"Content-Type: application/x-www-form-urlencoded",
"Content-Length: ".strlen($postjson)+5
);
$postoption = array('http' => array(
'method' => 'POST',
'header' => implode("\r\n", $header),
'content' => "json=".$postjson,
'timeout' => 1
));
$posturl = "http://localhost:123456/td.agent_log";
$postrlt = file_get_contents($posturl, false, stream_context_create($postoption));
変更後
$postdata = array(
'hoge' => $hoge,
'moge' => $moge
);
$postjson = json_encode($postdata);
$posturl = "http://localhost:123456/td.agent_log";
$ch = curl_init($posturl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'json='.$postjson);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$postrlt = curl_exec($ch);
curl_close($ch);
一般的にはCURLOPT_POSTFIELDSには$postdataなのだろうけど、
td-agentのhttpが受取りの場合curlだと
curl -XPOST localhost:123456:/td.agent_log -d 'json={hoge:a, moge:b'}'
のように最初にフォーマットが付くので一般的にはしなくて良い変換とかが入っている。
接続エラーが発生することもあるのでhttpじゃなくてunix_socket使うほうがBetter。
注意
curlをhttps接続で使う時は
putenv("NSS_SDB_USE_CACHE=yes");
をphpの頭等に加えること。
buffer/cacheが増加してメモリー使用量の監視アラートとかが飛んできます。
空きが少なくなると開放されるので動作自体には影響無さそうです。
参考: http://qiita.com/bezeklik/items/7e1ac9e5da39261be7bd