В практике автоматизации рассылок из 1С мы часто сталкиваемся с ситуациями, которые на первый взгляд кажутся мистическими. Одна из таких проблем: есть список получателей (например, 5 человек), настроена типовая рассылка отчета по расписанию. Четверым письмо приходит стабильно, а пятому — нет. При этом, если запустить ту же самую обработку вручную, письма получают все. В Журнале регистрации 1С ошибок нет, статус — "Выполнено".
Давайте разберем эту ситуацию подробно, выясним технические причины такого поведения и рассмотрим надежные способы решения.
Первое, что нам нужно понять: почему результат зависит от способа запуска? Казалось бы, код выполняется один и тот же. Однако есть два критических фактора:
Большинство современных почтовых серверов (MS Exchange, Exim, Postfix, облачные сервисы вроде Mail.ru или Yandex) имеют встроенные механизмы защиты от спама и перегрузок. Один из таких механизмов называется Throttling (регулирование полосы пропускания).
Когда 1С отправляет 5 писем подряд без пауз, для почтового сервера это выглядит как спам-атака или флуд. Сервер может иметь настройки:
DATA в рамках одной TCP-сессии.Если лимит превышен (например, на 5-м письме), сервер может вернуть не фатальную ошибку (код 5xx), а временную ошибку (код 4xx, например, 421 Too many messages или 450 Greylisted).
Почему мы не видим ошибку в 1С?
Стандартные механизмы БСП (Библиотеки Стандартных Подсистем) или простые обработки могут некорректно обрабатывать коды 4xx. Если сервер разрывает соединение, 1С может посчитать, что отправка завершена, или записать ошибку в глубокий лог, который не виден в обычном Журнале регистрации.
Журнал регистрации (ЖР) часто бесполезен в таких случаях, так как он фиксирует логический факт "Попытка отправки выполнена", но не детали сетевого обмена. Чтобы убедиться, что проблема именно в ответе почтового сервера, нам необходимо включить Технологический журнал (TechLog).
Давайте настроим сбор логов по событию MAIL. Для этого в файл logcfg.xml на сервере 1С добавим следующую настройку:
После сбора логов во время сбоя, мы увидим полный протокол общения с SMTP-сервером. Ищем строки, где после команд RCPT TO или DATA сервер возвращает ответ. Скорее всего, вы увидите что-то подобное на 5-м письме:
SMTP response: 421 4.7.0 Too many messages from 192.168.1.10
Разберем несколько способов исправления ситуации, от простых к архитектурно правильным.
Самое простое решение, которое подтвердило свою эффективность в рассматриваемой теме — снизить скорость отправки. Если проблема возникает из-за того, что мы отправляем письма слишком быстро, давайте добавим паузу.
Если вы пишете свой механизм рассылки, внутри цикла отправки можно добавить ожидание. В современных версиях платформы 8.3 есть нативные методы для асинхронных пауз, но в фоновом задании на сервере часто используют старый проверенный способ через команду Ping, так как метод Предупреждение или Ожидание там недоступен.
Для Каждого Адресат Из СписокПолучателей Цикл
// Формирование письма
// ...
// Отправка письма
Соединение.Послать(Письмо);
// Пауза 2 секунды, чтобы "успокоить" почтовый сервер
ЗапуститьПриложение("ping -n 2 127.0.0.1", , Истина);
КонецЦикла;
Плюсы: Легко реализовать.
Минусы: Увеличивает общее время выполнения задания. Это "костыль".
Это наиболее профессиональный подход, если содержимое письма (вложение) одинаково для всех получателей. Вместо того чтобы создавать 5 отдельных писем и 5 раз стучаться на почтовый сервер, мы формируем одно письмо.
Алгоритм действий:
ИнтернетПочтовоеСообщение.СлепыеКопии (BCC).
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Ежедневный отчет";
// Основной получатель (или технический ящик)
Письмо.Получатели.Добавить("main@company.com");
// Массовая рассылка через скрытую копию
Для Каждого Адрес Из МассивАдресов Цикл
Письмо.СлепыеКопии.Добавить(Адрес);
КонецЦикла;
// Одна отправка - одна сессия
Почта.Послать(Письмо);
Плюсы: Мгновенная отправка, минимальная нагрузка на сервер, 100% гарантия, что спам-фильтр по частоте не сработает.
Минусы: Не подходит, если каждому получателю нужно отправить уникальный отчет (например, расчетный листок).
Некоторые SMTP-серверы ограничивают количество писем в рамках одной сессии. Если вы открыли соединение командой Соединение.Подключиться() и в цикле шлете 100 писем, сервер может разорвать связь после 10-го.
Решение заключается в том, чтобы получить настройки учетных записей и обновлять соединение каждые N писем (или даже каждое письмо).
Профиль = Новый ИнтернетПочтовыйПрофиль;
// Заполнение профиля...
Для Каждого Адресат Из СписокПолучателей Цикл
Почта = Новый ИнтернетПочта;
Почта.Подключиться(Профиль); // Подключаемся заново для каждого письма
Попытка
Почта.Послать(СоздатьПисьмо(Адресат));
Исключение
ЗаписьЖурналаРегистрации("Ошибка почты", , , , ОписаниеОшибки());
КонецПопытки;
Почта.Отключиться(); // Разрываем сессию
КонецЦикла;
Этот метод работает медленнее, чем BCC, но надежнее, чем просто цикл, так как сбрасывает счетчики сессии на стороне сервера.
Если вы используете собственный почтовый сервер, убедитесь, что проблемы доставки не связаны с глобальными блокировками. Проверьте:
Если рассылка не работает выборочно и только в автоматическом режиме — это почти всегда срабатывание защиты почтового сервера от частых запросов. Рекомендуем начать с метода использования Скрытой копии (BCC), если это позволяет бизнес-логика, либо добавить принудительные паузы в цикл отправки.