top of page

Специфіка роботи БА в системах, побудованих на Шині Даних (Message Bus)

В сьогоднішньому швидкоплинному світі, коли комунікація і швидкість передачі повідомлень грають неймовірно важливу роль, того самого ми хочемо від великих технологічних систем. Нам потрібно, щоб застосунки або сервіси «спілкувалися» в режимі реального часу, і передача повідомлень займала мілісекунди. Цю задачу вирішує, серед іншого, побудова архітектури системи з використанням шини даних (message bus).

Шина даних – це специфічний тип інфраструктури, який дозволяє різним системам (або компонентам системи) комунікувати, використовуючи певний спільний інтерфейс, а сама шина виступає свого роду посередником між ними. Це дуже ефективний і надійний спосіб обміну даними між системами, який до того ж дуже добре масштабується, чому завдячує своєю популярністю. Крім того, на відміну від інших типів ‘communication architectures’ (приміром, клієнт-сервер або peer-to-peer), шина даних, будучи свого роду «брокером» для обміну повідомленнями між системами, дозволяє не встановлювати тісні зв’язки між сервісами або застосунками, що робить систему істотно більш гнучкою.


Що треба знати для ефективної роботи з шиною даних


Власне принцип роботи шини даних

В системі будуть ті компоненти чи сервіси, які публікуватимуть дані на шину, назвемо їх відправниками (senders), і ті, що читають ці повідомлення – отримувачі або споживачів (receivers/consumers). Для більшої структурованості й зручності зазвичай кожен компонент матиме свій «шматочок» на шині даних, який називають чергою повідомлень (message queue/ service queue). Абстрактно це щось на кшталт поштової скриньки певного абонента. Кожне повідомлення, яке відправляється на шину даних, матиме свою тему (topic), що має визначену структуру. Компоненти системи, які є споживачами даних (умовно – чекають конкретних повідомлень, щоб зробити певні дії з ними), будуть підписуватися на ці теми/топіки, щоб отримувати їх одразу в момент публікації. 


Приклад:

Є декілька компонентів трейдингової системи. Один ми називаємо «диспетчером», його задача – забирати всі нові замовлення клієнтів, форматувати їх належним чином і публікувати їх як повідомлення на шину даних з темою ХХХ/YYY/ZZZ/E/NEWO, де

  • XXX – код системи/застосунку

  • YYY – код підсистеми

  • ZZZ – код енвайрменту, в якому відбулась подія (адже їх декілька)

  • E – event (тип події)

  • NEWO – new order (назва події)

Другий компонент, назвемо його «адаптер», має свою чергу повідомлень і підписаний на вказану вище тему. Як тільки публікується нове повідомлення з такою темою, воно потрапляє в  чергу повідомлень адаптера. А задачею адаптера є додати до даних, які містяться в замовленні клієнта, внутрішні дані компанії, необхідні для його обробки, і опублікувати знову на шину даних з темою ХХХ/YYY/ZZZ/E/NEWO/ACTIVE.


В свою чергу, на тему ХХХ/YYY/ZZZ/E/NEWO/ACTIVE підписано ще два компоненти – «персистор», який зберігатиме нові замовлення в базу даних (переводячи в необхідний формат), і OMS система, яка власне далі оброблятиме замовлення.


Дуже часто системи, побудовані таким чином, називають подіє-базованими (event-based): є певна подія – вона у вигляді повідомлення публікується на шині даних, а інші компоненти її підхоплюють і роблять певні дії. Також такі системи найчастіше побудовані з використанням мікросевірсів. Крім вищенаведеного прикладу це може бути окремий мікросервіс, який в певний момент читає дані клієнтів з бази даних, переводить у потрібний формат і публікує повідомлення на шину даних. Задача іншого мікросервісу буде виключно забирати ці повідомлення, валідувати відносно даних з CRM, доповнювати їх, приміром, даними про наявні у кожного клієнта кошти, і знову публікувати на шину. Третій мікросервіс буде дозволяти або відхиляти спробу логіну кожного клієнта до системи, порівнюючі введені дані з цими повідомленнями з шини даних. І так далі.


Json та xml

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


Приклад події з даними клієнта

{

“type”: EventType_Customer”,

“header”: {

     “eventID”: “124nf;sdkgjp5849”,

     “type”: “EvtType_EVENT”,

     “subtype”: “EvtSubType_CUSTOMER_EVENT”,

     “timestamp”: “1716984729186”},

“customer”: {

     “Contact”: [{

          “ContactID”: “1234567”,

          “ContactName”: “John Smith”,

          “Role”: “trader”,

          “Default”: true}]

     “LegalEntity”: {

          “LegalEntityID”: “87655341”,

          “LegalEntityName”: “Trading Company Ltd.”,

          “LocationCode”: “LDN”,

          “CountryCode”: “UK”,

          “Tradeable”: true

   }

  }

}



Вміти читати логи

Це те, чому мені довелося вчитися, коли я потрапила на поточний проект. Адже повноцінне розуміння системи, з якою я працюю, по суті означає грунтовне розуміння всіх потоків даних між компонентами. Хто, що і в якому форматі публікує на шину даних, хто з нього читає і що має відбуватися далі. Це все я можу відслідкувати в логах кожного компоненту системи. Приміром, клієнт відправляє замовлення з UI, куди воно потрапляє? Як виглядає? Який компонент має його валідувати? Який прийняти/погодити? Що відбувається далі до моменту, коли замовлення можна вважати успішним (або не успішним).


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


Знати архітектуру (і дружити з архітектором)

Власне, підсумовуючи вище сказане – щоб описати будь-яку нову функціональну чи нефунціональну вимогу, треба чітко розуміти, як все в деталях працює зараз.

 

Що це все означає для БА


Істотно більше деталей, починаючи зі збору вимог

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


UML та інші інструменти

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


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


Для візуалізації взаємодії компонентів в рамках певного процесу, використовуємо діаграму послідновності (sequence diagram).


Приклад роботи з вимогами:


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


Зазвичай, я прописую ці вимоги за таким умовним темплейтом:

  • Чернова структура події/повідомлення, яке відправлятиметься на шину даних (на прикладі існуючих подій надаю свої пропозиції щодо того, як виглядатиме повідомлення, у форматі json)

  • Модель даних. В діаграмі класів розкаладаю це повідомлення на атрибути, і прописую можливі варіанти значень для кожного з них. В даному прикладі, оскільки в нас існує подія для створеного замовлення, і одним із атрибутів замовлення є статус – Active – ми можемо просто додати до існуючої моделі даних новий статус – Amend, а решту можна перевикористати

Модель даних для подій в шині даних

(бачимо, що подія OrderEvt є одним з підвидів більш загальної події Event. Як будь який івент в системі повинна мати три ID (eventID, lastID, ClientID), які її визначають.

OrderEvt має також декілька атрибутів:

  • OrderState, який може приймати значення New, Active, Amended (який ми додаємо в рамках вимог, над якими працюємо, Deleted, Closed);

  • Customer, який в свою чергу матиме перелік власних атрибутів, що його визначають ;

  • OrderType, який може приймати одне з трьох існуючих значень (Type1, Type2, Type3);

  • Product, який також може приймати одне з трьох існуючих значень.)


  • Пропонований топік, під яким ці івенти публікуватимуться на шину даних. В нашому прикладі, якщо ми мали топік ХХХ/YYY/ZZZ/E/NEWO/ACTIVE для нових активних замовлень, імовірно зміни публікуватимуться під топіком ХХХ/YYY/ZZZ/E/NEWO/AMEND 

  • Перелік компонентів чи сервісів, які будуть підписані на цей топік. В даному разі, приміром, той самий персистор, який оновить базу даних відповідним чином, і OMS система, яка далі оброблятиме замовлення

  • Потік даних (повідомлення опублікували на шину даних, що відбувається далі?). Найчастіше у вигляді діаграми послідовності, адже в даному разі дуже важлива послідовність подій. Для простого прикладу покажемо, що замовлення відправляється нам з фронтенду, потрапляє на шину даних, звідки його «забирає» якийсь мікросервіс «адаптер», який перевіряє його, додає до нього дані, повертає на шину в статусі Active, а звідти його зчитує знову ж наша UI (показує клієнту, що замовлення тепер активне).

Приклад для діаграми послідовності (sequence diagram)

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

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


Документація, документація, документація

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


Підтримка куа і команд сапорту

Зважаючи на високий рівень деталізації при зборі і описанні вимог, БА стає важливим центром знання про платформу. Тому дуже часто мене кличуть допомогти знайти причини помилки, яку зловила команда сапорту, або QA під час тестування.

 

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



Якщо ви маєте бажання поглибити свої технічні зання, зверніть увагу на тренінги Technical skillsfor Business Analyst и Advanced Technical skills for Business Analyst




681 перегляд0 коментарів

Comments


bottom of page