设定:
Nginx作为PHP-FPM的静态资源/反向代理。
我们的网站有一个search.product页面,该页面发出curl请求以从外部源获取其信息。 每个页面请求调用此类。在生产中没有回声,
基本PHP看起来像:
class myCurl
{
private $ch = NULL;
public function __construct()
{
$this->ch = curl_init();
}
public function __destruct()
{
if ($this->ch)
{
curl_close($this->ch);
$this->ch = NULL;
}
}
private function _callCurl($url)
{
curl_setopt($this->ch, CURLOPT_URL, $url);
curl_setopt($this->ch, CURLOPT_TIMEOUT, 15);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($this->ch);
if ($data === FALSE)
{
echo "No Data \n";
}
if (curl_errno($this->ch) === 28)
{
echo "Timeout \n";
}
if ($array = json_decode($data, TRUE))
{
return $array;
}
return FALSE;
}
}
我们的搜索页面,产品页面遭到机器人,谷歌,雅虎,bing的打击。
当他们遇到我们时,我们有时会看到nginx访问日志中的502,503,499错误增加。
我正在考虑三个选项,需要帮助才能做什么
选项: 1)更好的配置cURL ...不知道如何做到这一点,需要帮助。 2)使用php fsockopen移动到套接字...我听说这更快/更有效率 3)在我们的移民处投掷另一台服务器以减轻负担 4)不确定......有任何建议。
这些搜索结果无法缓存......它们非常独特,并且不会被普通用户真正访问过..它们包含大量的get参数。我们告诉机器人不要通过robots.txt抓住它们,但它们似乎并不在乎,因为我们在Google网站管理员工具中看到了很多服务器错误,这会损害我们的索引状态和排名。
在正常流量期间,我们看不到多少错误。
例如。让我们说,当搜索机器人击中我们时,我们每秒都会发出数百个卷曲请求,并且它们正在超时......无法使用缓存......有什么方法可以解决这个问题。我想的是另一台服务器。
请帮忙
答案 0 :(得分:1)
我怀疑其他PHP函数是否可以解决您的问题。 fsockopen()
可能会快一点,但如果您已经使用cURL,那么它绝对不值得付出努力。但是你应该自己在你的实际服务器上进行基准测试,这是一个不错的小微基准测试。将fsockopen()
代码放入f1()
正文,将curl()
放入f2()
。
<?php
// Make sure any errors are displayed.
ini_set("display_errors", true);
// You can use the following construct to create an A/B benchmark.
define('LOOP', 10000);
function f1() {
for ($i = 0; $i < LOOP; ++$i) {
}
}
function f2() {
for ($i = 0; $i < LOOP; ++$i) {
}
}
$time1 = -microtime(true);
f1();
$time1 += microtime(true);
$time2 = -microtime(true);
f2();
$time2 += microtime(true);
var_dump($time1, $time2);
首先,通过IP直接访问您的终端,或至少输入域的hosts文件中的IP。这将删除DNS查找或加快它们。
然后降低你的函数调用,可能是这样的:
<?php
class myCurl {
private $ch = NULL;
protected static $options = array(
CURLOPT_TIMEOUT => 15,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => 1,
);
public function __construct() {
$this->ch = curl_init();
curl_setopt_array($ch, static::$options);
}
public function __destruct() {
curl_close($this->ch);
}
private function _callCurl($url) {
curl_setopt($this->ch, CURLOPT_URL, $url);
$data = json_decode(curl_exec($this->ch), TRUE);
if ($data === (array) $data) {
return $data;
}
return FALSE;
}
}
当然,这个实现假设您的对象非常短暂,我不知道。如果我没有采用更简单的一次性方法来立即释放其资源。
<?php
final class MyCurl {
protected static $options = array(
CURLOPT_TIMEOUT => 15,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => 1,
);
protected function curlGET($url) {
$ch = curl_init($url);
curl_setopt_array($ch, static::$options);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($data === (array) $data) {
return $data;
}
return false;
}
}
如果您无法重复使用,那么在对象的整个生命周期内保持与目标服务器的连接并不是一个好主意。事实上,连接,获取数据并直接再次关闭它会更好。保持其他进程和其他客户端的连接免费。
我还建议优化操作系统级别的这类东西,上面的DNS /主机提示只是一个开始。优化您的TCP内核配置并加快速度。你可能会发现我在很久以前做过的以下存储库:
https://github.com/Fleshgrinder/sysctl.d/blob/master/sysctl.d.conf