Мы рассмотрели, какие бывают агенты. Теперь научимся их запускать на кроне. Мы сможем переложить часть задач с пользователей сайта на крон и ускорить время выполнения страниц.
Признаюсь. К этому снаряду я подходил несколько раз. И только с последнего толчка смог осилить этот вес. Сложность в том, что существует большое количество недокументированных констант и опций. Их совместное поведение совершенно не очевидно.
Константы, которые могут влиять на запуск агентов и отправку писем:
BX_CRONTAB
BX_CRONTAB_SUPPORT
NO_AGENT_CHECK
DisableEventsCheck
Опции модуля main, которые влияют на запуск агентов:
agents_use_crontab - по умолчанию не задана
check_agents - по умолчанию не задана
При этом не всё можно прочитать в исходном коде. Файл ядра Битрикса /bitrix/modules/main/include.php обфусцирован.
Нам надо повесить все агенты на крон.
Была подобная статья и учебный курс, но там есть фатальный недостаток: все почтовые события тоже вешаются на крон. Крон работает с минимальной частотой раз в минуту. Получается, что пользователь нажимает «восстановить пароль» и минуту ждет письмо. Еще один недостаток — статья устарела и в ней нет, как настроить резервное копирование по расписанию.
Нам надо, чтобы отправка писем была на хитах, а все агенты и резервное копирование работали на кроне.
Посмотрим, как сейчас обстоят дела в Битриксе:
По умолчанию на кроне вызывается файл /bitrix/modules/main/tools/cron_events.php:
В файле в самом начале стоит define("BX_CRONTAB", true);. Из-за этого в прологе устанавливается другая константа define("BX_CRONTAB_SUPPORT", true);. В результате данный крон-скрипт обрабатывает ТОЛЬКО непериодические агенты.
Исходный код функции обработки агентов.
function CheckAgents()
{
...
//For a while agents will execute only on primary cluster group
if((defined("NO_AGENT_CHECK") && NO_AGENT_CHECK===true) || (defined("BX_CLUSTER_GROUP") && BX_CLUSTER_GROUP !== 1))
return null;
$agents_use_crontab = COption::GetOptionString("main", "agents_use_crontab", "N");
$str_crontab = "";
if($agents_use_crontab=="Y" || (defined("BX_CRONTAB_SUPPORT") && BX_CRONTAB_SUPPORT===true))
{
if(defined("BX_CRONTAB") && BX_CRONTAB===true)
$str_crontab = " AND IS_PERIOD='N' ";
else
$str_crontab = " AND IS_PERIOD='Y' ";
}
...
return CAgent::ExecuteAgents($str_crontab);
}
Настройка агентов на кроне:
Проверьте, чтобы в файле dbconn.php не было установленных констант:
BX_CRONTAB
BX_CRONTAB_SUPPORT
NO_AGENT_CHECK
DisableEventsCheck
Установите опцию, которая запрещает выполнение агента в прологе:
COption::SetOptionString("main", "check_agents", "N");
echo COption::GetOptionString("main", "check_agents", "Y"); // должно вывестись N
Опция, которая влияет на выбор агентов в функции CheckAgents, должна быть не определена или "N".
COption::SetOptionString("main", "agents_use_crontab", "N");
echo COption::GetOptionString("main", "agents_use_crontab", "N"); // должно вывестись N
<?php
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/. ./..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true);
define('BX_NO_ACCELERATOR_RESET', true); // чтобы не глючило на VMBitrix 3.1 из-за Zend при отправке бэкапа в облако.
// здесь никакой агент не выполнится. Потому что мы сделали COption::SetOptionString("main", "check_agents", "N");
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
@set_time_limit(0);
@ignore_user_abort(true);
CAgent::CheckAgents(); // а вот тут все агенты выполнятся. И периодические, и непериодические
CEvent::CheckEvents(); // почтовые события мы оставили выполняться на хитах. Но и тут они могут выполняться. Почему нет?
define("BX_CRONTAB", true);
// модуль email-маркетинг
if(CModule::IncludeModule('sender'))
{
\Bitrix\Sender\MailingManager::checkPeriod(false);
\Bitrix\Sender\MailingManager::checkSend();
}
// а еще есть файлик резервного копирования, который запустится, когда его время придет.
require($_SERVER['DOCUMENT_ROOT']."/bitrix/modules/main/tools/backup.php");
?>
Пропишите правило в крон, например * * * * * /usr/bin/php -f /home/bitrix/www/bitrix/php_interface/cron_events.php
Результат
Теперь должно работать. Все агенты периодические и непериодические запускаются на cron. Все почтовые события отправляются на хитах пользователей сразу. Если к отправке письма привязана отправка SMS, то SMS тоже отправится сразу и не будет ждать крона.
Недостатки
Решение вполне рабочее, но есть проблемы:
1. Свой файл /bitrix/php_interface/cron_events.php, как и в старой статье, не будет обновляться.
Битрикс уже добавлял в крон резервное копирование по расписанию. Если они еще что-то добавят, то у вас не появится новый функционал.
2. В Виртуальной машине Битрикса уже настроен крон для файла /bitrix/modules/main/tools/cron_events.php. Вам придется настроить крон на свой файл /bitrix/php_interface/cron_events.php
Решение
Мы написали свой модуль «Агенты на кроне», который очень прост, удобен и лишен этих недостатков.
Дмитрий Помаскин, это означает, что вы должны написать агента так, чтобы он правильно выполнился на хитах (если агенты на хитах) и на кроне (если агенты на кроне).
На хитах проверить его просто. Обновите страницу несколько раз.
Если на хитах работает, то и на кроне заработает. Только имейте ввиду: на кроне другой массив $_SERVER. И определение текущей страницы будет другим.
Как на кроне проверить в условиях экзамена не очень представляю.
Можно как-то попытаться вызвать в консоли что-то вроде:
Подскажите пожалуйста в чем может быть ошибка. Запускаю команду вручную, получаю: Fatal error: Class 'CEvent' not found in /var/www/bitrix01/bitrix/modules/main/tools/cron_events.php on line 15
Подскажите пожалуйста в чем может быть ошибка. Запускаю команду вручную, получаю: Fatal error: Class 'CEvent' not found in /var/www/bitrix01/bitrix/modules/main/tools/cron_events.php on line 15
Невозможная ситуация это стандартный файл. Можете даже удалить наш модуль, чтобы убедиться что ошибка не в нем.
У меня файл /bitrix/modules/main/tools/cron_events.php выглядит так:
Проверьте, как выглядит ваш файл крона. Может быть у вас где-то криво настроены символические ссылки и не все подключается. Запустите тест битрикса по проверке модифицированных файлов ядра. (монитор качества внедрения, тест "Ядро продукта не модифицировалось")
Максименко Олег, спасибо большое! short_open_tag стоит в On и все равно не срабатывало. Помог запуск в таком виде /usr/bin/php -d display_errors -d short_open_tag /var/www/bitrix/modules/main/tools/cron_events.php
Максименко Олег, спасибо большое! short_open_tag стоит в On и все равно не срабатывало. Помог запуск в таком виде /usr/bin/php -d display_errors -d short_open_tag /var/www/bitrix/modules/main/tools/cron_events.php
Юрий Авдеев, настройки для крона не могут быть заданы в файлах .htaccess и httpd.conf. Настройки для крона должны быть указаны в php.ini и других ini-файлах которые участвуют при запуске php из консоли.
Поэтому проверьте на всякий случай, где у вас задаются настройки для PHP. Возможно, правильнее будет их перенести в php.ini.
Статья хорошая но для тех у кого при запуксе cron events из консоли для проверки выдает PHP Fatal error: require(): Failed opening required '/bitrix/modules/main/include/prolog_before.php' Необходимо в переменной убрать пробел в пути между точками вон видите в самом конце. - $_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/. ./..");
В этой теме Алексей Шафранский (Администратор) пишет, что инструкция по переводу всех агентов на крон в документации устарела и вполне достаточно настроек по умолчанию (bitrix-env) для выполнения всех агентов на кроне.
Петин Артём, в виртуальной машине крон включается из меню по SSH, прописывать в /etc/crontab больше не надо.
Чтобы агенты на кроне заработали установщик сайта (restore.php или bitrixsetup) сам зачем-то записывает BX_CRONTAB_SUPPORT в dbconn. Так у вас на кроне будут работать непереиодические агенты и отправка писем.
Именно так, а периодические на хитах. Но он утверждает, что все агенты, а не только непериодические. Это-то и вызвало вопрос.
Значит всё ещё актуальна необходимость установки вашего модуля или ручного изменения параметров check_agents / agents_use_crontab и добавления своего крон-скрипта?
В той статье, кстати, крон-скрипт обновили в марте этого года. Не подскажете, какой из скриптов оптимальнее использовать: из той статьи или из вашей?
terseto, установите модуль на тестовый сайт https://labs.1c-bitrix.ru/ а потом скопируйте /bitrix/modules/askaron.agents к себе. Модуль бесплатный. DisableEventsCheck не трогайте, она отключает отправку писем.
Потом установите define("BX_CRONTAB_SUPPORT", true); в dbconn.php
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».