Ну давай разберем. Все вокруг кричат про event sourcing и CQRS, но когда приходишь в проект с монолитом на PHP 5.6 и базой, где 20 лет копился спагетти-код, начинается цирк. Я за то, чтобы внедрять CQRS точечно: отделить read-модель от write-модели на уровне одного модуля, а не переписывать все с нуля. Иначе получите не CQRS, а просто второй монолит, который еще и синхронизировать надо.
Ключевой момент — не пытаться сделать идеально с первого раза. Берите один бизнес-процесс, например, обработку заказов, и стройте для него отдельную read-модель на простых SQL-вьюхах или материализованных представлениях. Остальное пока оставьте как есть. Через пару месяцев увидите реальный профит по нагрузке, а не по картинкам в презентации.
Если кто-то скажет, что без событийной шины это не CQRS — плюньте ему в лицо. События можно добавить потом, когда синхронные вызовы начнут реально мешать. Сначала — разделение ответственности, потом — все остальное.
👍 1
Полностью поддерживаю подход с точечным внедрением. Самое сложное в легаси — это не архитектура, а борьба с соблазном переписать всё сразу. У нас был похожий кейс: выделили read-модель для каталога товаров, просто повесили пару материализованных вьюх и обновили репозиторий. Никаких шин, никаких событий — просто `SELECT` вместо тех 15 JOIN’ов, которые убивали базу. Нагрузка на прод упала процентов на 40, и это без единого изменения в write-слое.
Единственное, что добавил бы от себя: сразу заложите компромисс по консистентности. Пока нет событий, read-модель будет слегка отставать, и это нормально для 90% бизнес-логики. Но обязательно пропишите это в коде — например, пометьте запросы аннотацией или вынесите в отдельный сервис, чтобы через полгода никто не удивлялся, почему данные «не свежие». Иначе через пару спринтов вам начнут прилетать тикеты с требованием «вернуть как было», и весь профит сгорит на согласованиях.
Материализованные вьюхи — рабочий вариант. Но стоит сразу зафиксировать SLA по задержке. Иначе read-модель превратится в источник багов, которые сложно отлаживать: write-слой пишет, read-слой читает, а между ними — провал.
Для легаси на PHP 5.6 ещё важен момент с транзакциями. Если обновление вьюхи происходит в той же транзакции, что и запись — это не CQRS, а просто нормализация. Настоящее разделение требует асинхронности. Но раз вы начинаете с точечного внедрения, лучше держать синхронное обновление, но явно вынести его в отдельный метод репозитория. Так хотя бы останется возможность потом заменить на очередь без переписывания бизнес-логики.
Согласна на все сто! Синхронное обновление read-модели в отдельном методе репозитория — это самый безопасный компромисс для старта. Только добавлю: сразу продумай идемпотентность и версионирование событий, иначе когда вы всё-таки перейдёте на очередь, повторы сообщений разнесут вьюхи в пух и прах.
И ещё момент по SLA: для легаси на PHP 5.6 я бы посоветовала не гнаться за «свежестью» данных, а зафиксировать допустимую задержку в 5–10 секунд. Это даст вам окно, чтобы без паники переложить обновление на фоновый воркер. А пока синхронно — обязательно логируй время выполнения каждого апдейта вьюхи, чтобы было видно, где начинаются проблемы с производительностью. Иначе получится как в моей практике: read-модель молчала, пока нагрузка не выросла, и все баги вылезли в самый неподходящий момент 😅
👍 1👎 1