Pull to refresh

Comments 11

Это поверх messaging надо еще городить еще один механизм? а как же low coupling между микросервисами при разработке таких костылей можно просто работать с монолитом — так как у вас все равно тесная зависимость на контракты другого сервиса, и если меняеться домен сервиса как либо надо диплоить все зависимость — и код обновлять?

Допустим у Вас есть 2 системы:


1. монолитный Dynamic CRM, отвечающий за учет стока на складах и построение отчетов-
2. микросервисный Stock Service, отвечающий за общее число товаров на сайтах, кол-во доступных товаров для данного сайта и резервацию товаров пользователями.


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


Естественно обе системы связаны сервисом интеграции через Messages Queue, поскольку производительность приложений разная.


Что произойдет если кол-ва начнут расходиться
1. вы можете продать больше товаров, чем у вас есть на самом деле и как следствие потерять клиента
2. не распродать весь сток и тем самым нанести компании убытки


Для мониторинга подобных проблем как раз и пишется сервис реконсиляции, запускающийся каждый час.

Что произойдет если кол-ва начнут расходиться
1. вы можете продать больше товаров, чем у вас есть на самом деле и как следствие потерять клиента
2. не распродать весь сток и тем самым нанести компании убытки

Понятно. То о чем вы говорите называется требование strong write consistency.
Вашим подходом вы не решаете эту проблему вроде как проблему. Если там кто-то у вас руками решает конфликты и получает письма, с сагами, например, вы можете собственно делать тоже самое и даже больше(делать роллбек не руками, в момент покупки и обеспечивать транзакционность даже для распределенных данных). При этом не уходя от event driven дизайна системы, не изобретая велосипед и не создавая связей между сервисами.

Еще можно обратить внимание на дизайн сервисов. Где находиться Core domain — например если склад первичен, то резервация по идее и должна делаться через него. В read-only стейт Stock Service вообще вроде как не имеет требований строгой read консистентности(там банально из-за concurrency может закончиться товар пока он лежит в корзине).

Реконсиляции — инструмент мониторинга целостности данных, а не способ устранения причины, почему данные разошлись. При этом ряд конфликтов (расхождений) действительно можно разрешить автоматически, но этим мы лечим следствие, а не причину.


То что вы описываете в комменте — способ устранение причины. Но конкретном случае мы не можем внести изменения в Dynamic CRM (Navision) и свести все к одному источнику данных.

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

Сериализация и вычисление хеша действительно быстрее прямолинейого множественного сравнения строк и чисел через AND?
Да, если хеш вычислен заранее. Нет, если хеш вычисляется при сравнении.
Насколько я понял, в вашем случае, приложение реконсилляции подключается в двум разным базам, проводит аналитику, и показывает разницу по-экземплярно?

В 3 из 4 случаев реконсилируются приложения WebApi vs WebApi, в оставшемся WebApi vs SQL, поскольку интерфейс не поддерживает бачевые методы, либо структура данных избыточна — большой оверхед на транспорт и сериализацию.


Если перед вами стоит задача реконсилировать SQL vs SQL и базы находятся на одном сервер, то проще и эффективнее написать SQL jobs. Но при таком подходе придется следить за изменениями в структуре БД, в этом плане использовать API с версиями намного проще.


Сериализация и вычисление хеша действительно быстрее прямолинейого множественного сравнения строк и чисел через AND?

Здесь больший фокус на универсальности, получается идентичная структура таблицы, одинаковый запрос на сравнение и константная стоимость хранения.


По факту большая часть ресурсов тратится на получение данных по HTTPS и десериализация объектов. Оверхед на функцию GetHashCode() минимальный (взгляните на ее код).

Теперь понятно.
Для озвученных объемов, возможно, самый оптимальный.
Стас, очень хорошая статья с точки зрения описания технического решения. Особенно понравились картинки и схемы. Но мне не хватило в начале статьи более подробного описания того в чем проблема, какие подходы к решению этой проблемы есть и почему то решение, что ты привел является наиболее оптимальным. В каком случае оно подойдет, а в каком случае его лучше не использовать.
Sign up to leave a comment.

Articles