280  /  415

Запуск агентов из cron

Достаточно часто возникает необходимость переноса исполнения некоторых особо тяжелых агентов на cron.

Механизм запуска

Перейдите на страницу Настройки > Инструменты > Командная PHP-строка и исполните следующий код:

COption::SetOptionString("main", "agents_use_crontab", "Y");
echo COption::GetOptionString("main", "agents_use_crontab", "N");

Увидели "Y". С этой секунды на хитах будут исполняться только периодические агенты.

Перейдите на страницу Настройки > Настройки продукта > Агенты и настройте показ колонки Периодический (для контроля). И отредактируйте нужные вам агенты выставив галочку Периодический.

В cron добавьте на выполнение команду:

/usr/bin/php -f /var/www/bitrix/modules/main/tools/cron_events.php

Выставьте периодичность, например: */10 * * * * - что означает раз в десять минут.

Примечание: Непосредственно перед выполнением задания процедура запуска агентов пытается отменить ограничение:
@set_time_limit(0);
ignore_user_abort(true);

Если set_time_limit разрешен, то время выполнения может превышать то, что стоит в настройках файла php.ini.

Но необходимо помнить, что есть ограничения со стороны хостера: на объем памяти, время выполнения, периодичность запуска и т.д.

Обобщенное решение для выполнения всех агентов из-под cron

Для начала полностью отключим выполнение агентов на хите. Для этого выполним следующую команду в php консоли:

COption::SetOptionString("main", "agents_use_crontab", "N"); 
echo COption::GetOptionString("main", "agents_use_crontab", "N"); 

COption::SetOptionString("main", "check_agents", "N"); 
echo COption::GetOptionString("main", "check_agents", "Y");

В результате выполнения должно быть "NN".

После этого убираем из файла /bitrix/php_interface/dbconn.php определение следующих констант:

define("BX_CRONTAB_SUPPORT", true);
define("BX_CRONTAB", true);

И добавляем в этот файл:

if(!(defined("CHK_EVENT") && CHK_EVENT===true))
   define("BX_CRONTAB_SUPPORT", true);

Создаем файл проверки агентов и рассылки системных сообщений /bitrix/php_interface/cron_events.php:

<?
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/../..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];

define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true); 
define('CHK_EVENT', true);

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

@set_time_limit(0);
@ignore_user_abort(true);

CAgent::CheckAgents();
define("BX_CRONTAB_SUPPORT", true);
define("BX_CRONTAB", true);
CEvent::CheckEvents();

if (CModule::IncludeModule("subscribe"))
{
      $cPosting = new CPosting;
      $cPosting->AutoSend();
} 
?>

И добавляем данный скрипт в cron:

*/5 * * * * /usr/bin/php -f /home/bitrix/www/bitrix/php_interface/cron_events.php

После этого все агенты и отправка системных событий будут обрабатывается из под cron, раз в 5 минут.

Примечание: Время выполнения можно скорректировать в соответствие с проектом. Кроме того, есть возможность через установку большого значения mail_event_bulk сделать более "быстрой" доставку почтовых уведомлений. Установка проверки раз в минуту вместе с отправкой за раз 100 сообщений, сделает для пользователей незаметным данную задержку.

Чтобы не увеличивалась очередь отправки почтовых сообщений, рекомендуется изменить параметр отвечающий за количество почтовых событий обрабатываемых за раз. Для этого выполняем в php консоли следующую команду:

COption::SetOptionString("main", "mail_event_bulk", "20"); 
echo COption::GetOptionString("main", "mail_event_bulk", "5");

Если очередной запуск cron_events.php произошёл до завершения работы ранее запущенного скрипта, то запуска агентов не произойдет и скрипт завершит свою работу. (Так как агенты блокируются на время выполнения.) В данном случае обработка ничем не отличается от обработки на хите, новый хит может произойти в тот момент когда еще не отработали агенты на предыдущем.

Еще пример

Вот типичный код скрипта, запускаемого из-под cron:

#!/usr/bin/php 
<?php 
$_SERVER["DOCUMENT_ROOT"] = "/home/hosting/www"; 
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"]; 
define("NO_KEEP_STATISTIC", true); 
define("NOT_CHECK_PERMISSIONS", true); 
set_time_limit(0); 
define("LANG", "ru"); 
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); 

//ваш код... 

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php"); 
?> 

50

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии