+7 495 008 8452 пн.-пт. 10:00 – 17:00
Если у вас возникли какие либо вопросы которые вы не смогли решить по нашим публикациям самостоятельно,
то ждем ваше обращение в нашей службе тех поддержки.


Выполнение всех агентов на cron. Чтобы почта была на хитах

Мы рассмотрели, какие бывают агенты. Теперь научимся их запускать на кроне. Мы сможем переложить часть задач с пользователей сайта на крон и ускорить время выполнения страниц.

Признаюсь. К этому снаряду я подходил несколько раз. И только с последнего толчка смог осилить этот вес. Сложность в том, что существует большое количество недокументированных констант и опций. Их совместное поведение совершенно не очевидно.

Константы, которые могут влиять на запуск агентов и отправку писем:
  • 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:

<?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 не было установленных констант:
  • 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


    Свой крон-скрипт:

    Создайте файл /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


    Решение

    askaron_agents_marketplace.png

    Мы написали свой модуль «Агенты на кроне», который очень прост, удобен и лишен этих недостатков.

    Статья: Агенты на кроне — теперь просто


  • Назад в раздел

    Подписаться на новые материалы раздела:












    CAPTCHA