Я спрашивал хостинг об ошибке 500, которая случается иногда и вот что они ответили:
spoilerThis email is in regards to your open ticket concerning the 500 error on your site. We have investigated the site and the cause of the errors and it looks to be the mysql script. It runs every minute calling the database and that creates what we call a "user connection" and you only can have 15 at a time running. The crons do not drop the connection so after 15 mins you already take up the connections so then when you try and go to the site you see the 500 error because there are no more connections available.
We would recommend that you troubleshoot your cron so it doesn't run as frequent or its able to close the user connection after its done calling the database. Thank you for the opportunity to assist you today. There is a three question survey linked at the bottom of this email if you can let me know how I did - all feedback helps! If you have any further questions, please feel free to reply to this email and Ill be more than happy to lend a hand.
Насколько я понимаю они указывают на то, что я не закрываю соединение с БД.
Я использую вот такой сценарий:
spoilerfunction Connect () {
include("config.php");
$DB = new mysqli($DB_SERVER, $DB_USER, $DB_PASS, $DB_BASE);
return $DB;
}
class Script {
private $DB;
public function __construct($DB)
{
$this->DB = $DB;
}
function MultiCurlRequest ($data)
{
$multi = curl_multi_init();
$handles = [];
$array = [];
foreach ($data as $key)
{
$ch = curl_init();
$url = "https://123.ru";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 50);
curl_multi_add_handle($multi, $ch);
$handles[] = array(
'url' => $ch,
'Ip' => $key["Ip"],
'QtyVerifyTime' => $key["QtyVerifyTime"]
);
}
$active = null;
do {
$mrc = curl_multi_exec($multi, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($multi) == -1) {
usleep(10000);
// continue;
}
do {
$mrc = curl_multi_exec($multi, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
foreach ($handles as $handle)
{
$result = curl_multi_getcontent($handle["url"]);
$array[] = array(
'Ip' => $handle["Ip"],
);
curl_multi_remove_handle($multi, $handle["url"]);
}
curl_multi_close($multi);
return $array;
}
}
$DB = Connect();
$object = new Script($DB);
$object->CheckList (); // старт идет тут.
за 1 минуту в multi curl приходит на текущий момент не более 10 запросов по которым он должен сделать обращение и дождаться ответа, это делается через proxy и ответ иногда может быть долгим, до time out который установлен 50 секунд.
Вызов ф-ции MultuCurlRequest идет из другой ф-ции (которая выполняет задачу выборки из БД и передает нужные данные в ф-цию)
Вот собственно она:
spoilerfunction CheckList ()
{
$LIMIT = 10;
$query = $this->DB->query("SELECT Ip, Port FROM sc_list WHERE Status = 0 ORDER BY Id DESC LIMIT " . $LIMIT . "");
if (!empty($query->num_rows)) {
$result = $this->MultuCurlRequest($query);
}
if (!empty($result)) {
foreach ($result as $value) {
// обрабатываем результат который вернула ф-ция. (Запросы к БД)
}
}
return true;
}
Может кто-то подскажет, что тут не так? где нужно закрывать соединение с БД?) Или может хостер опять наплетает?
Выборка из БД занимает не более 1-2 секунды, затем curl запрос ограничен 50 секундами (получается все 10 запросов даже если proxy не работает будут висеть 50 секунд и скрипт завершится) в целом скрипт не должен работать больше чем 55-57 секунд, т.е. таким образом скрипт завершается и закрывается соединение с БД (автоматически как сказали эксперты) тогда я не понимаю, как я могу превысить лимит 15 одновременно открытых соединений с БД?) Конечно, помимо меня работают еще Cron Задачи около 15 штук, но я создал отдельный user для этого сценария, или 15 - это ограничение по всем юзерам?
И еще, что имеют ввиду
The crons do not drop the connection so after 15 mins
как понять кроны не закрывают соединение? я закрываю их, или может я делаю это не правильно?)