Признаюсь. К этому снаряду я подходил несколько раз. И только с последнего толчка смог осилить этот вес. Сложность в том, что существует большое количество недокументированных констант и опций. Их совместное поведение совершенно не очевидно.
Константы, которые могут влиять на запуск агентов и отправку писем:
- BX_CRONTAB
- BX_CRONTAB_SUPPORT
- NO_AGENT_CHECK
- DisableEventsCheck
- agents_use_crontab - по умолчанию не задана
- check_agents - по умолчанию не задана
Нам надо повесить все агенты на крон.
Была
Нам надо, чтобы отправка писем была на хитах, а все агенты и резервное копирование работали на кроне.
Посмотрим, как сейчас обстоят дела в Битриксе:
По умолчанию на кроне вызывается файл /bitrix/modules/main/tools/cron_events.php:
<?php $_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/. ./. ./. ./.."); $DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"]; define("NO_KEEP_STATISTIC", true); define("NOT_CHECK_PERMISSIONS",true); define("BX_CRONTAB", true); define('BX_NO_ACCELERATOR_RESET', true); require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); @set_time_limit(0); @ignore_user_abort(true); CEvent::CheckEvents(); if(CModule::IncludeModule('sender')) { \Bitrix\Sender\MailingManager::checkPeriod(false); \Bitrix\Sender\MailingManager::checkSend(); } require($_SERVER['DOCUMENT_ROOT']."/bitrix/modules/main/tools/backup.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 не было установленных констант:
Установите опцию, которая запрещает выполнение агента в прологе:
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 |
Свой крон-скрипт:
Создайте файл /bitrix/php_interface/cron_events.php:
<?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
Решение

Мы написали свой модуль «
Статья:
Но он утверждает, что все агенты, а не только непериодические. Это-то и вызвало вопрос.
Значит всё ещё актуальна необходимость установки вашего модуля или ручного изменения параметров check_agents / agents_use_crontab и добавления своего крон-скрипта?
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/. ./..");