php 如何加速php中的cURL?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19467449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to speed up cURL in php?
提问by toy
I'm trying to get embed tweet from Twitter. So, I'm using cURL to get the json back. I wrote a little test but the test takes around 5 seconds as well as when I run locally. So, I'm not sure what am I doing wrong here.
我正在尝试从 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;
}
When I paste the link and test it from the browser it's really fast.
当我粘贴链接并从浏览器测试它时,它真的很快。
采纳答案by Kristian
With respect to environment, I've observed in PHP that cURL typically runs very fast in most environments except in places where there is low CPU and there is slower network performance. For example, on localhost on my MAMP installation, curl is fast, on a larger amazon instance, curl is fast. But on a small crappy hosting, i've seen it have performance issues where it is noticeably slower to connect. Though, i'm not sure exactly whythat is slower. Also, it sure wasn't 5 seconds slower.
关于环境,我在 PHP 中观察到,cURL 通常在大多数环境中运行得非常快,除了在 CPU 低且网络性能较慢的地方。例如,在我的 MAMP 安装的 localhost 上,curl 很快,在较大的亚马逊实例上,curl 很快。但是在一个糟糕的小型主机上,我发现它存在性能问题,连接速度明显变慢。虽然,我不确定为什么这会变慢。此外,它肯定不会慢 5 秒。
to help determine if its PHP or your environment, you should try interacting with curl via the command line. At least that you'll be able to rule out PHP code being the problem if its still 5 seconds.
为了帮助确定是 PHP 还是您的环境,您应该尝试通过命令行与 curl 交互。至少,如果它仍然是 5 秒,您将能够排除 PHP 代码是问题。
回答by Michael Ozeryansky
The best speed up I've ever had was reusing the same curl handle.
Replace $ch = curl_init( $json_url );
with curl_setopt($ch, CURLOPT_URL, $url);
. Then outside the functions have one $ch = curl_init();
. You'll need to make $ch
global in the functions to access it.
我曾经拥有的最好的加速是重复使用相同的卷曲手柄。替换$ch = curl_init( $json_url );
为curl_setopt($ch, CURLOPT_URL, $url);
。那么外面的功能就有了$ch = curl_init();
。您需要$ch
在函数中将其设为全局才能访问它。
Reusing the curl handle keeps the connection to the server open. This only works if the server is the same between requests, as yours are.
重用 curl 句柄保持与服务器的连接打开。这仅在请求之间的服务器相同时才有效,就像您的一样。
回答by CoverUp
The final solution for speed up is this
加速的最终解决方案是这样的
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
Regards
问候
回答by ncs
Try to set
curl_setopt($ch, CURLOPT_ENCODING, '')
it's enable gzip compression
尝试设置
curl_setopt($ch, CURLOPT_ENCODING, '')
它启用 gzip 压缩
回答by Michael Sivolobov
To speed up cURL I recommend create special class for API (e.g. ApiClient
) and use one shared cURL handler, only change URL for every request. Also cut off requests for name resolving and use gzipped response.
为了加速 cURL,我建议为 API 创建特殊类(例如ApiClient
)并使用一个共享的 cURL 处理程序,只为每个请求更改 URL。还切断名称解析请求并使用 gzip 响应。
I needed to process about 1 million entities every day from one API-server that limits us to use only one concurrent connection. I created that class. I hope it will help others in optimising their curl requests.
我每天需要从一个 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);
}
}
Also if you don't have limitations to have only one connection with server you can use curl_multi_*
functions.
此外,如果您没有限制与服务器只有一个连接,您可以使用curl_multi_*
功能。
回答by Frank
Try
尝试
CURLOPT_TCP_FASTOPEN => 1
... to activate TCP-Fast-Open.
... 激活 TCP-Fast-Open。
It was added to cURL 7.49.0, added to PHP 7.0.7.
它已添加到 cURL 7.49.0,添加到 PHP 7.0.7。
回答by mustafa candan
Try using ipv-4 only. In default curl uses ipv-6 and its slow. I added --ipv4 parameter to my curl command and cost drops 8 second to 4 second
尝试仅使用 ipv-4。默认 curl 使用 ipv-6 并且它很慢。我在 curl 命令中添加了 --ipv4 参数,成本下降了 8 秒到 4 秒