Pull to refresh

Comments 10

UFO just landed and posted this here

Что-то я статью не понял, в чем проблема отослать письмо через месяц? Ставить крон на месяц это глупость несусветная, а вдруг скрипт упадет, следующая попытка будет ещё через месяц? Вроде давно изученный кейс: пишем задачу в базу с датой выполнения. Некий скрипт/воркер работает постоянно (каждую минуту/час) и проверяет базу на наличие подходящих задач по дате и шлёт письма, если упал, то повторит работу через минуту/час.

Сейчас стало модно все усложнять. Эта статья отличный пример как из просто сделать космолёт и делать вид что это правильно.

В реальной жизни все будет не так. Не будет одного письма через месяц. Будет каждый день список клиентов, которым требуется отправить вот эти "черезмесячные" письма.

Как пример. Задача, которой не так давно сам занимался. Задача называется "рассылка уведомлений клиентам". Там много (порядка десятка) разных критериев, для простоты опишу один - по сроку действия ДУЛ (документ удостоверяющий личность).

Итак, есть клиент-владелец счета. У клиента есть список ДУЛ, один из которых помечен как "основной". К этому счету могут быть привязаны карты на других лиц (например, на членов семьи). У этих людей тоже есть основной ДУЛ.

У каждого ДУЛ есть срок действия. Например паспорт РФ меняется по достижении владельцем 21-го (по-моему) и 45-ти лет.

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

  • Если до окончания срока действия основного ДУЛ осталось менее 30-ти дней и предупреждение еще не посылалось - посылается предупреждение. Если это владелец счета, то ему и всем его держателям карт. Если это держатель, то только ему.

  • Если срок действия основного ДУЛ истек, то, аналогичным образом рассылаются сообщения о блокировке.

Никакого "спящего кода" тут нет. Просто каждый день в определенное время (точнее, определенный период времени) запускается программный модуль, делающий выборку из БД по установленным критериям и по этой выборке формируются нужные сообщения (после чего в соотв. таблице БД делается пометка что сообщение послано).

Архитектурно все очень просто. Там есть хитрости на уровне кода чтобы все это максимально быстро работало в плане выборок, но это уже технические детали.

На прошлой работе была иная задача. Там события были менее отдаленные - "через минуту", "через 15 минут", "через час"... И программа основная работала в режиме 27/7.

Там была очередь событий. Фактически - список, отсортированный по времени. Туда по необходимости помещалось (в нужное место) событие в виде временной метки + тип (в заголовке) и данных (в теле).

В отдельном потоке работал обработчик очереди событий, который раз в секунду проверял время события в голове списка. Если меньше или равно текущему - событие извлекалось из списка и отправлялось на обработку (в соответствующий его типу обработчик события - ему передавался тип и данные, он уже знал что со всем этим делать дальше). Обработанное событие удалялось из очереди (или, если это периодическое событие, снова помещалось в очередь уже в новое место в соответствии с новой временной меткой).

Как по мне, очень мерзкая парадигма сокрытия сложности там, где ее скрывать не надо.

Ок, разобрались с версиями кода и обратной совместимостью, ок, разобрались с обработкой ошибок. Но вот как спрогнозировать нагрузку и очереди в таких системах, кажется, становится невыполнимой задачей. По классике со складыванием задач в базу все контролируемо и очевидно. Да, надо чуть пописать кода, по процесс извлечения запланированных задач из базы полностью прозрачен. Тут же, как поведет себя система, условно, 1 января в 00:00, если, вдруг, окажется, что система должна чего-то там серьёзно шевелиться при смене года, хз. Конечно, фанбои публичных облаков возразят мне, что это вообще не проблема. Условно, если надо поднять миллион лямбд одновременно, то это не проблема, а лишь расходы. Но, увы, не все так просто масштабируется. Есть лимиты API у тех же смс/имейл провайдеров, есть пределы у БД, если надо актуализировать данные, есть пределы у систем логгирования/аналитики/антифрода.

За месяц может многое изменится, API key почтового сервиса, сам сервис, даже необходимость отправки письма может уже отпасть , это касается всех типов отложенных задач. В случае с таким вот "sleep" я так понял фиксируются не только что надо сделать, но и как, а это как через месяц будет другим

В примечании в конце текста написали, что можно таки и по ходу дела обновлять. Но, согласен, выглядит, как велосипед, написанный под задачу, при формулированнии которой забыли указать NFR о возможности подправки бизнес-процесса в процессе его выполнения.

Вообще, это извечная боль продактов, которые не прошли путь инженера, а пришли к должности через дизайн/продажи/оперейшн. Продакт формулирует задачу, даже не держа в голове поддерживаемость, работу с ошибками, точки масштабирования, необходимость аналитики и так далее. Очень гордая собой команда создает "идеальную" архитектуру под ТЗ, которая вот просто как нельзя лучше решает задачу, делая это производительно, красиво, лаконично, так, что хоть статьи пиши, хоть на конференциях выступай. Потом, во время пилотной эксплуатации всплывают доп требования, которые ну вот вообще не ложатся в задумку, и, либо решение обрастает костылями, теряя свою красоту, и становясь по ряду критериев хуже решений лобовых и очевидных (как правило)

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

либо команда идет писать новую архитектуру под обновленное ТЗ, и всё пишут заново

Тем более, что в реалиях будет база клиентов. У каждого дата регистрации и отметка послано "черезмесячное письмо" или нет. И вся задача запустить раз в сутки сервис, который сделает выборку из БД по условию "регистрация больше или равна месяцу назад и письмо не посылалось". Выбранным клиентам будут разосланы письма и установлены метки о посылке.

И таких клиентов будет каждый день. Городить для каждого отдельный "спящий" сервис - ну такое себе. Если их будет несколько десятков миллионов.

Тут еще дело в том, что если клинетов будет хотя бы сотня тысяч - это на каждого отдельный спящий сервис нужен? А с учетом того, что дата регистрации у каждого своя и посылать письма нужно будет каждый день (тем или иным клиентам, кому срок подошел), сам подход со спящими сервисами выглядит крайне нерациональным. Достаточно одного сервиса рассылки писем тем, кому срок подошел, с однократным ежедневным запуском.

Sign up to leave a comment.