Информация об изменениях

Сообщение Re[47]: Помогите правильно спроектировать микросервисное при от 22.02.2026 11:52

Изменено 22.02.2026 11:53 ·

Re[47]: Помогите правильно спроектировать микросервисное при
Здравствуйте, Sinclair, Вы писали:

S>·>Вопрос о том, как сервис резервации будет взаимодейтсвовать с субд. Получил сервис резервации гигантский объект и пока его жуёт — все остальные должны ждать на блокировках.

S>Представления о гигантскости объектов сильно искажены идиотскими реализациями hibernate-based приложений.
S>Вот в кровавом рич DDD это действительно может стать проблемой: мы начали транзакцию, в которой мееееееееееееееееееедленно такаем складские остатки из базы в апп-сервер, потом их обновляем и меееееееееееееееееееееееееедленно записываем обратно.
S>Когда код пишется прямыми запросами к СУБД, заказ в тыщу позиций обработается примерно мгновенно. Особенно если данные лежат на современном SSD диске.
S>Я уже неоднократно сталкивался с тем, что у людей сдвинута интуиция относительно быстродействия СУБД на современном железе. Лет несколько тому кто-то меня уверял, что реляционка захлебнётся на обходе графа из миллиона элементов. Оказалось — нет, даже у лаптопа пред-предыдущего поколения вполне хватает дури обрабатывать такое незаметно для пользователя.
Возможно, что мои знания устарели...

S>·>Представь себе, есть куча заказов одной популярной сковородки. И большинство заказов из одной позиции именно на эту сковородку. И тут кто-то запулливает гигантский ордер, среди позиций есть эта сковородка. Придётся ждать всем!

S>О да. Двадцать миллисекунд придётся подождать.
Для FX-трейдинга — задержка 20мс — это production issue. Типичная latency — 0.3мс.

S>·>Да и вообще неясно в чём преимущество заталкивать всё в одну транзакцию.

S>Преимущества транзакций — в согласованности. Мы вот взяли и придумали какие-то инварианты, отражающие ограничения бизнеса. Транзакции — единственный способ обеспечить распределённые инварианты (то есть несводимые к ограничениям на 1 элемент данных. Проверки типа "возраст не может быть отрицательным" можно сделать и без транзакций).
S>Вот есть, к примеру, инвариант "статус относится ко всему заказу — черновик, зарезервирован, оплачен, отгружен, получен и т.п." На этот инвариант полагается масса кода, включая отчёты.
S>Если мы отменяем этот инвариант, придётся переделывать примерно всё.
Так ведь у нас уже есть бизнес-сущность "частично зарезервированный заказ". Поэтому уже неважно — на 99.9% или на 0.1% зарезервированный. Алгоритмы будут те же.

S>>>Опять же, это распиливание мы можем сделать безо всяких раундтрипов, передав в СУБД список успешно зарезервированных позиций в удобном для неё виде.

S>·>Как без раундрипов резервировать с успехом/неуспехом каждую позицию?
S>Язык SQL много чем плох, а вот прекрасен он батч-операциями. Можно отдать ему стейтмент, который поменяет сразу много позиций.
S>В моём предыдущем примере позиции либо менялись, либо не менялись все разом; небольшое изменение предиката приведёт к тому, что позиции будут резервироваться частично.
Батчинг — это уже ортогонально бизнес-требованиям, это нефункциональное требование. Можно батчами обрабатывать входные заявки на резервацию. Они мелкие, зафигачивай сразу кусками по 100 штук (или сколько намерим оптимально). Опять же — суть в том, что размер транзакции фиксированный, а не зависит от данных идущих от юзеров. Это, кстати, сразу бесплатно даёт более эффективную обработку мелких заказов. Ломанулась куча народа покупать по скидке одну сковородку — фигня, будут обработаны пачками максимально быстро.

S>·>Тут дело принципиальное — чтобы система была responsive, надо гонять мелкие сообщения. Пока кафка передаёт гигантское сообщение — другим сообщениям придётся ждать своей очереди. Ждут все! А если большое сообщение разбить на мелкие части, то ждать будет только тот, кому надо много.

S>Повторюсь: если Кафка становится узким местом, нужно выкинуть кафку. В рассматриваемом мной примере никакой Кафки нет, и ждут только те, кто ждёт. Ну и, опять же, в современных сетях всё происходит достаточно шустро. Главное — минимизировать количество раунд-трипов.
Это скорее про поточную, конвеерную обработку. Когда идут потоки сообщений туда-сюда, друг друга не мешая, с минимальными блокировками.

S>·>Тут нужен at-least-once. Да, и при redelivery тоже придётся гигантское сообщение дублировать.

S>Редчайший случай, заказ на тысячу позиций. Какого характерного размера это "гигантское" сообщение? В непожатом JSON оно будет занимать полсотни килобайт. Семечки.
В высокопроизводительных системах — порядка сотен байт.
Re[47]: Помогите правильно спроектировать микросервисное при
Здравствуйте, Sinclair, Вы писали:

S>·>Вопрос о том, как сервис резервации будет взаимодейтсвовать с субд. Получил сервис резервации гигантский объект и пока его жуёт — все остальные должны ждать на блокировках.

S>Представления о гигантскости объектов сильно искажены идиотскими реализациями hibernate-based приложений.
S>Вот в кровавом рич DDD это действительно может стать проблемой: мы начали транзакцию, в которой мееееееееееееееееееедленно такаем складские остатки из базы в апп-сервер, потом их обновляем и меееееееееееееееееееееееееедленно записываем обратно.
S>Когда код пишется прямыми запросами к СУБД, заказ в тыщу позиций обработается примерно мгновенно. Особенно если данные лежат на современном SSD диске.
S>Я уже неоднократно сталкивался с тем, что у людей сдвинута интуиция относительно быстродействия СУБД на современном железе. Лет несколько тому кто-то меня уверял, что реляционка захлебнётся на обходе графа из миллиона элементов. Оказалось — нет, даже у лаптопа пред-предыдущего поколения вполне хватает дури обрабатывать такое незаметно для пользователя.
Возможно, что мои знания устарели...

S>·>Представь себе, есть куча заказов одной популярной сковородки. И большинство заказов из одной позиции именно на эту сковородку. И тут кто-то запулливает гигантский ордер, среди позиций есть эта сковородка. Придётся ждать всем!

S>О да. Двадцать миллисекунд придётся подождать.
Для FX-трейдинга — задержка 20мс — это production issue. Типичная latency — 0.3мс.

S>·>Да и вообще неясно в чём преимущество заталкивать всё в одну транзакцию.

S>Преимущества транзакций — в согласованности. Мы вот взяли и придумали какие-то инварианты, отражающие ограничения бизнеса. Транзакции — единственный способ обеспечить распределённые инварианты (то есть несводимые к ограничениям на 1 элемент данных. Проверки типа "возраст не может быть отрицательным" можно сделать и без транзакций).
S>Вот есть, к примеру, инвариант "статус относится ко всему заказу — черновик, зарезервирован, оплачен, отгружен, получен и т.п." На этот инвариант полагается масса кода, включая отчёты.
S>Если мы отменяем этот инвариант, придётся переделывать примерно всё.
Так ведь у нас уже есть бизнес-сущность "частично зарезервированный заказ". Поэтому уже неважно — на 99.9% или на 0.1% зарезервированный. Алгоритмы будут те же.

S>>>Опять же, это распиливание мы можем сделать безо всяких раундтрипов, передав в СУБД список успешно зарезервированных позиций в удобном для неё виде.

S>·>Как без раундрипов резервировать с успехом/неуспехом каждую позицию?
S>Язык SQL много чем плох, а вот прекрасен он батч-операциями. Можно отдать ему стейтмент, который поменяет сразу много позиций.
S>В моём предыдущем примере позиции либо менялись, либо не менялись все разом; небольшое изменение предиката приведёт к тому, что позиции будут резервироваться частично.
Батчинг — это уже ортогонально бизнес-требованиям, это нефункциональное требование. Можно батчами обрабатывать входные заявки на резервацию. Они мелкие, зафигачивай сразу кусками по 100 штук (или сколько намерим оптимально, параметр в конфиге). Опять же — суть в том, что размер транзакции фиксированный, а не зависит от данных идущих от юзеров. Это, кстати, сразу бесплатно даёт более эффективную обработку мелких заказов. Ломанулась куча народа покупать по скидке одну сковородку — фигня, будут обработаны пачками максимально быстро.

S>·>Тут дело принципиальное — чтобы система была responsive, надо гонять мелкие сообщения. Пока кафка передаёт гигантское сообщение — другим сообщениям придётся ждать своей очереди. Ждут все! А если большое сообщение разбить на мелкие части, то ждать будет только тот, кому надо много.

S>Повторюсь: если Кафка становится узким местом, нужно выкинуть кафку. В рассматриваемом мной примере никакой Кафки нет, и ждут только те, кто ждёт. Ну и, опять же, в современных сетях всё происходит достаточно шустро. Главное — минимизировать количество раунд-трипов.
Это скорее про поточную, конвеерную обработку. Когда идут потоки сообщений туда-сюда, друг друга не мешая, с минимальными блокировками.

S>·>Тут нужен at-least-once. Да, и при redelivery тоже придётся гигантское сообщение дублировать.

S>Редчайший случай, заказ на тысячу позиций. Какого характерного размера это "гигантское" сообщение? В непожатом JSON оно будет занимать полсотни килобайт. Семечки.
В высокопроизводительных системах — порядка сотен байт.