Обробка змін в архітектурі мікросервісів, керованих подіями


9

Я роблю дослідницький проект, де досліджую варіанти обробки змін в архітектурі мікросервісів, керованих подіями.

Отже, скажімо, ми отримали додаток, де ми отримали чотири різні сервіси. Кожна з цих служб має власну базу даних для зберігання локальних даних.

У цьому налаштуванні чотири служби спілкуються один з одним за допомогою шини подій. Тож коли щось трапляється в службі, він публікує подію. Усі інші служби, які зацікавлені в цій події, оброблять її по-своєму.

У такому випадку різні служби в архітектурі повинні мати "договори" про зміст цих подій (атрибути тощо). Тож служби мають "слабо пов'язані залежності" від цих подій

Моє запитання: як можна впоратись із змінами в цих подіях?

Отже, скажімо, сервіс A реєструє нових користувачів у додатку. Таким чином, він надсилає подію "UserRegistered". Служба B підбирає цю подію та обробляє її. Але деякі розробники в команді сервісу C вирішили, що їм також потрібна стать зареєстрованого користувача. Тому подія змінено і гендер атрибута додається до події "UserRegistered".

Як ми можемо переконатися, що служба B все ще може взяти ту саму подію з цим додатковим атрибутом без перерозподілу?

І чи є інші способи наблизитись до цієї проблеми після версії цих подій?


Який формат ваших повідомлень, чи це щось, що ви можете створити? Деякі формати повідомлень містять додаткові атрибути. Залежно від реалізації читача, ви можете додавати необов'язкові атрибути, не потребуючи оновлення всіх читачів.
Томас Оуенс

Я вільний у виборі формату для моїх повідомлень. Я думаю, що використання JSON - це найкращий шлях. Важливо, щоб ці різні сервіси були побудовані різними мовами. Ось чому необхідний загальний формат, наприклад XML або JSON.
CGeense

Відповіді:


1

Події - це не те, що змінилося. Вони збираються, коли щось змінилося.

Я можу створити систему подій, повністю відокремлену від змісту, який змінився. Таким чином, все, що я дізнаюся з події - це те, що об’єкт було оновлено. Якщо мені навіть байдуже, що об’єкт було оновлено, то я скажу все, що знає, як поговорити з цим об’єктом, щоб піти запитати, що змінилося

Це не вирішує проблему передачі цих змін. Це просто заважає йому стати частиною системи подій.

Прикладом одного із способів вирішення проблеми різних версій даних є спостереження створити та передати спостережуваному об'єкту колекцію. Спостережуваний об’єкт заповнює колекцію своїми останніми даними, і коли контроль повертає вас (спостерігача), маєте те, що вам потрібно. Якщо є додаткові речі, про які вам все одно, адже ви ніколи про неї не чули, ви просто ігноруєте її.

Багато інших способів зняти цю кішку, але саме в цьому випадку я працював.


Хіба це не різко збільшить трафік між службами? Використовуючи приклад у запитанні, UserRegisteredподія, якщо відбулася подія, яка не містила інформації про користувача, на шині буде 1 опубліковане повідомлення, а потім {кількість зацікавлених служб} запитів до служби користувача або опубліковані повідомлення до автобуса. Тоді з'являться {кількість зацікавлених служб} повідомлення різного розміру. Хоча я думаю, що це, мабуть, чистіша конструкція на папері, якщо продуктивність викликає занепокоєння, вона руйнується в будь-якій нетривіальній системі, особливо в мережі.
Томас Оуенс

@ThomasOwens Надсилання даних разом із подією означає, що якщо у мене N спостерігачів, я надсилаю N повідомлень. Самостійне надсилання події означає, що я надсилаю 3N повідомлення, лише 1 з яких має пакет даних. Це ваги просто чудово навіть у мережі. Єдиний істотний мінус - це втричі перевищити відставання. Не кажучи про те, що ви не можете знайти більш оптимальне рішення для конкретної ситуації. Я демонструю, що системи подій та версії даних не повинні з'єднуватися.
candied_orange

1
Вся ідея цього автобуса подій полягає в тому, щоб відключити різні послуги. Використовуючи частину проміжного програмного забезпечення, ми можемо переконатися, що ці служби не знають один одного і можуть існувати та спілкуватися, не знаючи про існування один одного. Якщо ми видалимо стан з цих подій і дозволимо службам безпосередньо з'єднуватися між собою, ми з'єднуємо ці служби. Таким чином, ми ніколи не можемо повторно використовувати один сервіс, не
потребуючи

1
Суть у тому, що система подій чи не потрібні розширювані дані. JSON або XML роблять це добре, якщо ви не змінюєте імена або структури, які були раніше встановлені. Я робив те ж саме з колекціями. Система заходів не повинна дбати про гендери. Якщо він надсилає дані, він повинен просто передати їх, і щось на іншому кінці буде або піклуватися про гендер, або не буде.
candied_orange

1

Такі рамки, як NServiceBus, справляються з цим, використовуючи версію подій за допомогою поліморфної розсилки повідомлень.

Наприклад, версія 1 Служби A може опублікувати подію як IUserRegistered_v1. Коли в сервісі версії 1.1 потрібно включити додаткове поле, воно може оголосити інтерфейс IUserRegistered_v1_1, який успадковуватиме IUserRegistered_v1, а також оголошувати деякі додаткові поля.

Коли Служба A публікує подію IUserRegistered_v1_1, NServiceBus відправить повідомлення на всі кінцеві точки, які обробляють або IUserRegistered_v1, або IUserRegistered_v1_1.


0

Поступове вдосконалення

Проста зміна моделі полягає в тому, що коли слухачі реєструються в якості спостерігача, вони включають список або іншу структуру елементів даних, про які вони хочуть знати. Це може працювати, якщо дані, повернені з сервісу, прості, але якщо у вас є достатня кількість ієрархічних даних, реалізувати це може бути дуже складно.

Скелі тверді

Якщо ви дійсно хочете отримати надійний спосіб зробити цей дизайн сервісом таким, щоб він зберігав історію змін, які були внесені до даних, які він зберігає. По суті, ви ніколи не оновлюєте записи у вашій базі даних, ви додаєте нові записи, де кожен з них представляє зміни. Кожен з цих нових записів пов'язаний з ідентифікатором події, який ідентифікує дію. Зберігається рівномірний запис із усією відповідною інформацією про зміну (хто, що, коли тощо). Це має деякі інші переваги, які виходять за рамки цієї відповіді, але обговорюються в цій статті про теорему САР .

Коли внесені зміни, ви створюєте запис про події та додаєте всі нові дані до вашої бази даних. Потім ви публікуєте слухачам подію, яка містить (мінімально) ідентифікатор події. Тоді слухачі можуть запитувати дані, пов’язані з цим ідентифікатором, та отримати версію даних, пов’язаних із цим. Тоді кожен слухач може отримати все необхідне, не зв'язуючи потреби інших різних слухачів разом. Я б радив, щоб ви додали до повідомлення про події підмножину найчастіше використовуваних полів даних, щоб слухачі могли відфільтрувати події, які їх не цікавлять. Це може зменшити чатість процесу, а деякі слухачі, можливо, ніколи не потребуватимуть дзвінків назад взагалі. Це також захищає вас від проблем із термінами. Якщо ви просто зателефонували до служби та отримали дані на основі ключа, можливі й інші зміни між отриманням події та завантаженням даних про неї. Це може не мати значення для всіх слухачів, але це може створити великі проблеми, якщо вам потрібно знати про всі зміни. Подальше вдосконалення дизайну, сумісне з цим підходом, якщо ви дійсно хочете повернути його до 11.

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


-1

@CandiedOrange робить вагомий пункт у коментарі до власної відповіді щодо розширюваних форматів даних, таких як xml.

Це не має значення, поки ви додаєте дані. Однак надайте розумні значення за замовчуванням для старих подій / необов’язкових полів.

Вам слід буде лише оновити служби, які вас цікавлять - в даному випадку - гендер. Аналізатор xml / json повинен мати можливість ігнорувати додаткові дані для інших служб. Це, звичайно, залежить від вашого вибору формату аналізу аналізатора та даних про події.

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


Моя думка полягає в тому, що їй потрібно впоратися зі всілякими змінами. Подумайте про службу, яка транслює подію. І ця подія містить властивість, яка застаріла і її слід видалити. Навіть якщо ці інші сервіси не використовують майно, воно порушить їх просто тому, що вони цього очікують. Тому я читаю цю статтю на martinfowler.com про споживчі договори: martinfowler.com/articles/consumerDrivenContracts.html При застосуванні цього принципу. Кожен провайдер (подія) знає, що від нього чекає. з цією інформацією він може підтвердити, якщо він порушить споживачів.
CGeense
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.