Как заставить FluentCRM отправлять массовые рассылки через очередь Mail Queue и не убить SMTP-сервер
Введение Если на сайте WordPress стоит FluentCRM, FluentSMTP и Mail Queue, кажется, что массовые рассылки должны автоматически уходить через очередь: сначала письма складываются в Mail Queue, затем WordPress cron постепенно отдаёт их в FluentSMTP, а уже FluentSMTP отправляет письма через SMTP-сервер. В идеале схема должна выглядеть так: Такая архитектура нужна, чтобы не отправлять сотни или…
Введение
Если на сайте WordPress стоит FluentCRM, FluentSMTP и Mail Queue, кажется, что массовые рассылки должны автоматически уходить через очередь: сначала письма складываются в Mail Queue, затем WordPress cron постепенно отдаёт их в FluentSMTP, а уже FluentSMTP отправляет письма через SMTP-сервер.
В идеале схема должна выглядеть так:
FluentCRM
↓
Mail Queue
↓
FluentSMTP
↓
SMTP-сервер
↓
Получатель Такая архитектура нужна, чтобы не отправлять сотни или тысячи писем одним рывком. Без очереди можно быстро упереться в лимиты SMTP-провайдера, получить временные блокировки, ухудшить доставляемость или создать лишнюю нагрузку на сайт.
На практике связка FluentCRM + FluentSMTP + Mail Queue может работать не так, как ожидается. Тестовые письма WordPress попадают в очередь, а массовые кампании FluentCRM могут уходить напрямую через FluentSMTP, минуя Mail Queue.
Ниже — разбор проблемы, диагностика и рабочее решение.
Исходная задача
На сайте использовались:
- FluentCRM Pro;
- FluentSMTP;
- Mail Queue;
- внешний cron на хостинге;
- отключённый встроенный WP-Cron.
Задача была следующая: отправлять рассылки на 300, 1000, 5000, 10000 и более подписчиков, но не выпускать все письма сразу в SMTP-сервер.
Нужна была контролируемая очередь:
- письма сначала попадают в Mail Queue;
- очередь может быть поставлена на паузу;
- скорость отправки задаётся в настройках Mail Queue;
- SMTP получает письма постепенно;
- в логе видно, какие письма были отправлены.
Настройки Mail Queue
В Mail Queue была включена отправка через очередь:
Status: Enabled
Send max: 60 emails every 1 minute Это означает, что очередь должна отправлять максимум 60 писем в минуту.
Если рассылка идёт на 350 человек, минимальное ожидаемое время отправки при таком лимите:
350 / 60 = 5.8 минуты Если 350 писем ушли за 20-30 секунд, значит Mail Queue фактически не ограничивал отправку.
Настройки cron
В wp-config.php был отключён стандартный WP-Cron:
define( 'DISABLE_WP_CRON', true ); Это правильная настройка, но только при одном условии: cron должен запускаться сервером или панелью хостинга.
Пример команды для cron:
curl -s --resolve webmarketing-lab.ru:443:87.236.16.31 https://webmarketing-lab.ru/wp-cron.php?doing_wp_cron > /dev/null 2>&1 Здесь:
webmarketing-lab.ru— домен сайта;443— HTTPS-порт, его оставляем;87.236.16.31— IP-адрес конкретного сайта;wp-cron.php?doing_wp_cron— запуск задач WordPress cron.
Если встроенный WP-Cron отключён, а внешний cron не работает, очередь будет наполняться, но письма не будут уходить.
Оптимальная частота запуска cron зависит от хостинга:
- для массовых рассылок cron желательно запускать каждую минуту;
- интервал 5 минут подходит только для сайтов, где очередь используется редко и скорость доставки не критична;
- если хостинг ограничивает cron, нужно ориентироваться на доступный минимум.
Почему тестовое письмо не доказывает работу массовой рассылки
Важный момент: если тестовое письмо появилось в Mail Queue, это ещё не значит, что массовая кампания FluentCRM тоже пойдёт через Mail Queue.
Обычные письма WordPress, например:
- сброс пароля;
- уведомления форм;
- тестовые письма;
- системные письма сайта;
обычно проходят через стандартную функцию WordPress:
wp_mail() Mail Queue как раз перехватывает wp_mail() и складывает письма в очередь.
Но массовые рассылки CRM-плагинов иногда используют собственные механизмы отправки, фоновые задания и внутренние очереди. Поэтому проверять нужно не просто тестовое письмо, а именно тестовую кампанию FluentCRM.
Симптомы проблемы
Проблема проявлялась так:
- в Mail Queue → Queue пусто;
- в Mail Queue → Log нет сотен записей после кампании;
- письма приходят получателям быстро;
- пауза Mail Queue не останавливает отправку;
- тестовые письма WordPress при этом попадают в очередь.
Особенно важный признак — количество записей в логе Mail Queue.
Если была отправка на 343 получателя, а в логе Mail Queue всего 20-30 записей, значит массовая кампания почти наверняка не прошла через очередь.
Как FluentCRM отправляет письма
После проверки кода FluentCRM стало ясно, что FluentCRM использует стандартную функцию WordPress:
wp_mail(
$to,
$data['subject'],
$data['body'],
$headers
); То есть теоретически Mail Queue должен перехватывать такие письма.
Значит проблема была не в том, что FluentCRM полностью обходит wp_mail().
Проблема оказалась в другом.
Где возник конфликт
И Mail Queue, и FluentSMTP вмешиваются в процесс отправки писем WordPress.
Mail Queue должен перехватить письмо, положить его в базу данных и отправить позже.
FluentSMTP должен взять письмо и отправить его через SMTP.
Но если FluentSMTP срабатывает раньше, письмо уходит сразу:
FluentCRM
↓
wp_mail()
↓
FluentSMTP
↓
SMTP На этапе диагностики создавалось впечатление, что кампании FluentCRM обходят очередь. Однако дальнейшая проверка показала, что FluentCRM также использует wp_mail(), а проблема находилась на уровне перехвата и обработки письма.
Как проверить гипотезу
Самый простой тест:
- Временно отключить FluentSMTP.
- Перевести Mail Queue в режим
Paused. - Отправить тестовую кампанию FluentCRM на 1-2 адреса.
- Открыть Mail Queue → Queue.
Если письмо появилось в очереди со статусом queue, значит:
- FluentCRM использует
wp_mail(); - Mail Queue работает;
- проблема практически выглядит как конфликт порядка выполнения между Mail Queue и FluentSMTP.
Если Mail Queue стоит на паузе, а письмо всё равно пришло получателю, значит очередь не перехватывает отправку.
Решение: поднять приоритет Mail Queue
Практическое решение состояло в том, чтобы изменить приоритет обработчика Mail Queue. После этого Mail Queue начал перехватывать письма до того, как они уходили дальше в SMTP-обработку.
Для этого можно добавить сниппет через WPCodeBox или другой менеджер сниппетов.
Название сниппета:
Mail Queue: Force Queue Before FluentSMTP Код:
add_action('plugins_loaded', function () {
global $wdm_wpma_options;
global $wdm_wpma_pre_wp_mail_priority;
if (
empty($wdm_wpma_options['enabled']) ||
!in_array($wdm_wpma_options['enabled'], ['1', 'paused'], true) ||
wp_doing_cron() ||
!function_exists('wdm_wpma_prewpmail')
) {
return;
}
remove_filter(
'pre_wp_mail',
'wdm_wpma_prewpmail',
$wdm_wpma_pre_wp_mail_priority
);
$wdm_wpma_pre_wp_mail_priority = 1;
add_filter(
'pre_wp_mail',
'wdm_wpma_prewpmail',
$wdm_wpma_pre_wp_mail_priority,
2
);
}, 999); В WPCodeBox для PHP-сниппетов открывающий тег <?php не используется. В других менеджерах сниппетов правила могут отличаться.
Что делает этот код
Сниппет проверяет, включён ли Mail Queue. Если очередь выключена, он ничего не делает.
Затем он проверяет, загружена ли функция Mail Queue:
function_exists('wdm_wpma_prewpmail') После этого сниппет удаляет старый обработчик Mail Queue и добавляет его заново с более высоким приоритетом:
$wdm_wpma_pre_wp_mail_priority = 1; В результате Mail Queue начинает срабатывать раньше FluentSMTP.
После исправления схема становится такой:
FluentCRM
↓
wp_mail()
↓
Mail Queue
↓
очередь в базе WordPress
↓
WP Cron
↓
FluentSMTP
↓
SMTP-сервер Как проверить результат за 30 секунд
После установки сниппета нужно провести контрольный тест.
- Перевести Mail Queue в режим
Paused. - Отправить тестовую кампанию FluentCRM на 1 адрес.
- Открыть Mail Queue → Queue.
Если всё настроено правильно:
- письмо появится в Queue;
- статус будет
queue; - письмо не придёт получателю, пока очередь на паузе.
Это значит, что перехват работает.
Если письмо сразу пришло получателю, а Queue осталась пустой, значит Mail Queue не участвует в отправке этой кампании.
Затем нужно вернуть Mail Queue в режим Enabled.
После этого письмо должно перейти:
queue
↓
sent и уйти через FluentSMTP.
Во вкладке Log должны появляться события:
queue-paused;queue-enabled;sent.
Это означает, что Mail Queue действительно управляет отправкой.
Нужно ли дополнительно ограничивать FluentCRM
В FluentCRM есть собственная настройка скорости:
Maximum Emails Per Second Например, если стоит 4, это означает до 4 писем в секунду, то есть до 240 писем в минуту.
Если Mail Queue настроен на 60 писем в минуту, то основным ограничителем должна быть именно очередь.
В процессе тестирования также использовался дополнительный сниппет для ограничения внутренней скорости FluentCRM:
/**
* FluentCRM: безопасная отправка массовых рассылок.
* Аналог схемы "очередь + крон", но внутри FluentCRM.
*/
add_filter('fluent_crm/email_limit_per_second', function($limit, $emailSettings = null, $handler = null) {
return 1; // 1 письмо в секунду = 60 писем в минуту
}, 10, 3);
add_filter('fluent_crm/mailer_handler_chunk_size', function($chunkSize) {
return 5; // маленькая пачка обработки
});
add_filter('fluent_crm/mailer_multi_thread_chunk_size', function($chunkSize) {
return 5; // ограничиваем многопоточную обработку
});
add_filter('fluent_crm/process_subscribers_per_request', function($count) {
return 10; // сколько подписчиков готовить за один проход
}); Он снижает скорость отправки до 1 письма в секунду, уменьшает размер пачек обработки и ограничивает многопоточную подготовку писем.
Этот код может быть полезен, если Mail Queue не используется или если сайт работает на слабом хостинге и нужно дополнительно снизить нагрузку на фоновые задачи FluentCRM.
Но после того как Mail Queue начал корректно перехватывать письма, необходимость в этом сниппете отпала. В финальной конфигурации используется только основной сниппет изменения приоритета Mail Queue:
Mail Queue: Force Queue Before FluentSMTP Причина простая: в рабочей схеме главным регулятором скорости становится Mail Queue:
FluentCRM
↓
Mail Queue
↓
WP Cron
↓
FluentSMTP Если после отключения дополнительного сниппета сайт снова начинает обрабатывать кампании слишком резко, его можно вернуть как дополнительную страховку.
Главное правило: не включать сразу несколько ограничителей без понимания, какой из них реально управляет отправкой. Иначе можно получить слишком медленную рассылку и сложную диагностику.
Рекомендуемые настройки
Для большинства проектов можно начать с такой конфигурации.
FluentCRM:
Maximum Emails Per Second: 1-4 Если Mail Queue работает правильно, это не главный лимит, но лучше не ставить слишком агрессивные значения.
Mail Queue:
Status: Enabled
Send max: 60 emails every 1 minute FluentSMTP:
SMTP включён
From Email соответствует домену
Return-Path включён WP-Cron:
define( 'DISABLE_WP_CRON', true ); И внешний cron на хостинге:
curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1 Если сайт использует Cloudflare, прокси, нестандартный DNS или нужно обращаться к конкретному IP, можно использовать вариант с --resolve:
curl -s --resolve example.com:443:SERVER_IP https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1 Для каких объёмов подходит это решение
Это решение подходит для массовых рассылок, но важно понимать: Mail Queue не отменяет лимиты SMTP-провайдера. Он только распределяет отправку во времени.
При лимите 60 писем в минуту примерное время отправки будет таким:
Расчёты являются теоретическими и предполагают, что cron выполняется регулярно, SMTP-сервер не вводит дополнительных ограничений, а сервер успевает обработать очередь.
| Размер базы | Примерное время |
|---|---|
| 300 писем | 5 минут |
| 1000 писем | 17 минут |
| 5000 писем | 1 час 23 минуты |
| 10000 писем | 2 часа 47 минут |
| 15000 писем | 4 часа 10 минут |
| 20000 писем | 5 часов 33 минуты |
Если SMTP-провайдер разрешает меньше писем в час или в сутки, лимит Mail Queue нужно снижать.
Например, если провайдер разрешает 1000 писем в час, безопасный лимит:
1000 / 60 = 16 писем в минуту То есть Mail Queue лучше настроить не на 60, а примерно на 10-15 писем в минуту.
Для баз 10000-20000+ подписчиков такое решение может работать, но только если:
- SMTP-провайдер разрешает такие объёмы;
- домен прогрет;
- SPF, DKIM и DMARC настроены;
- база подписчиков качественная;
- есть отписка;
- нет резких скачков жалоб на спам;
- cron стабильно работает;
- сервер выдерживает фоновые задачи WordPress.
Для регулярных больших рассылок на десятки тысяч адресов лучше рассматривать профессиональные email-сервисы или SMTP-сервисы, рассчитанные на bulk email.
Контрольный чек-лист перед большой рассылкой
Перед запуском кампании на всю базу нужно проверить:
- Mail Queue включён;
- FluentSMTP включён;
- внешний cron работает;
- в
wp-config.phpстандартный WP-Cron отключён только если внешний cron настроен; - тестовая кампания попадает в Queue;
- в режиме
Pausedписьмо не доставляется; - в режиме
Enabledписьмо переходит изqueueвsent; - в Log появляются записи отправки;
- скорость Mail Queue соответствует лимитам SMTP;
- доменная почта настроена через SPF, DKIM и DMARC;
- в письме есть корректная ссылка отписки.
Только после этого стоит запускать рассылку на всю базу.
Итог
Главная проблема была не в cron, не в SMTP и не в самом FluentCRM.
FluentCRM действительно отправляет письма через wp_mail(), а Mail Queue умеет эти письма перехватывать.
Практически проблема выглядела как конфликт порядка выполнения обработчиков Mail Queue и FluentSMTP.
Мы доказали три вещи: при включённом FluentSMTP очередь не работала, при выключенном FluentSMTP очередь работала, а после изменения приоритета Mail Queue начал перехватывать письма и очередь заработала.
После этого итоговая архитектура стала правильной:
FluentCRM
↓
wp_mail()
↓
Mail Queue
↓
очередь WordPress
↓
WP Cron
↓
FluentSMTP
↓
SMTP
↓
получатель В результате рассылки можно отправлять безопаснее: письма видны в очереди, отправку можно поставить на паузу, скорость контролируется, а SMTP-сервер не получает резкую нагрузку одним большим залпом.
