[英]How to speed up cURL in php?
我正在嘗試從 Twitter 嵌入推文。 所以,我使用 cURL 來取回 json。 我寫了一個小測試,但測試需要大約 5 秒以及我在本地運行時的情況。 所以,我不確定我在這里做錯了什么。
public function get_tweet_embed($tw_id) {
$json_url = "https://api.twitter.com/1/statuses/oembed.json?id={$tw_id}&align=left&omit_script=true&hide_media=false";
$ch = curl_init( $json_url );
$start_time = microtime(TRUE);
$JSON = curl_exec($ch);
$end_time = microtime(TRUE);
echo $end_time - $start_time; //5.7961111068726
return $this->get_html($JSON);
}
private function get_html($embed_json) {
$JSON_Data = json_decode($embed_json,true);
$tw_embed_code = $JSON_Data["html"];
return $tw_embed_code;
}
當我粘貼鏈接並從瀏覽器測試它時,它真的很快。
我曾經擁有的最好的加速是重復使用相同的卷曲手柄。 替換$ch = curl_init( $json_url );
與curl_setopt($ch, CURLOPT_URL, $url);
. 然后在函數外面有一個$ch = curl_init();
. 您需要在函數中將$ch
設為全局才能訪問它。
重用 curl 句柄保持與服務器的連接打開。 這僅在請求之間的服務器相同時才有效,就像您的一樣。
加速的最終解決方案是這樣的
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
問候
嘗試設置curl_setopt($ch, CURLOPT_ENCODING, '')
它啟用 gzip 壓縮
為了加速 cURL,我建議為 API 創建特殊類(例如ApiClient
)並使用一個共享的 cURL 處理程序,只為每個請求更改 URL。 還切斷名稱解析請求並使用 gzip 響應。
我每天需要從一個限制我們只能使用一個並發連接的 API 服務器處理大約 100 萬個實體。 我創建了那個類。 我希望它能幫助其他人優化他們的 curl 請求。
class ApiClient
{
const CURL_TIMEOUT = 3600;
const CONNECT_TIMEOUT = 30;
const HOST = 'api.example.com';
const API_TOKEN = 'token';
/** @var resource CURL handler. Reused every time for optimization purposes */
private $ch;
/** @var string URL for API. Calculated at creating object for optimization purposes */
private $url;
public function __construct()
{
$this->url = 'https://' . self::HOST . '/v1/entity/view?token=' . self::API_TOKEN . '&id=';
// Micro-optimization: every concat operation takes several milliseconds
// But for millions sequential requests it can save a few seconds
$host = [implode(':', [ // $host stores information for domain names resolving (like /etc/hosts file)
self::HOST, // Host that will be stored in our "DNS-cache"
443, // Default port for HTTPS, can be 80 for HTTP
gethostbyname(self::HOST), // IPv4-address where to point our domain name (Host)
])];
$this->ch = curl_init();
curl_setopt($this->ch, CURLOPT_ENCODING, ''); // This will use server's gzip (compress data)
// Depends on server. On some servers can not work
curl_setopt($this->ch, CURLOPT_RESOLVE, $host); // This will cut all requests for domain name resolving
curl_setopt($this->ch, CURLOPT_TIMEOUT, self::CURL_TIMEOUT); // To not wait extra time if we know
// that api-call cannot be longer than CURL_TIMEOUT
curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, self::CONNECT_TIMEOUT); // Close connection if server doesn't response after CONNECT_TIMEOUT
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); // To return output in `curl_exec`
}
/** @throws \Exception */
public function requestEntity($id)
{
$url = $this->url . $id;
curl_setopt($this->ch, CURLOPT_URL, $url);
$data = curl_exec($this->ch);
if (curl_error($this->ch)) {
throw new \Exception('cURL error (' . curl_errno($this->ch) . '): ' . curl_error($this->ch));
}
return $data;
}
public function __destruct()
{
curl_close($this->ch);
}
}
此外,如果您沒有限制只能與服務器建立一個連接,您可以使用curl_multi_*
函數。
關於環境,我在 PHP 中觀察到,cURL 通常在大多數環境中運行得非常快,除了在 CPU 低且網絡性能較慢的地方。 例如,在我的 MAMP 安裝的 localhost 上,curl 很快,在較大的亞馬遜實例上,curl 很快。 但是在一個糟糕的小型主機上,我發現它存在性能問題,連接速度明顯變慢。 雖然,我不確定為什么會變慢。 此外,它肯定不會慢 5 秒。
為了幫助確定是 PHP 還是您的環境,您應該嘗試通過命令行與 curl 交互。 至少,如果它仍然是 5 秒,您將能夠排除 PHP 代碼是問題。
試試
CURLOPT_TCP_FASTOPEN => 1
... 激活 TCP-Fast-Open。
它已添加到 cURL 7.49.0,添加到 PHP 7.0.7。
嘗試使用--ipv4
參數。
這將強制 curl 僅使用 ipv-4 並忽略與某些設備仍然不太兼容並減慢進程的 ipv-6。 將--ipv4
添加到我的 curl 命令將成本從 8 秒減少到 4 秒。 這是 %50 快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.