Автономні мікросервіси, черги на події та виявлення послуг


15

Останнім часом я багато читав про мікро-сервіси, і ось кілька висновків, які я дійшов до цього часу (будь ласка, виправте мене, якщо я помиляюся в будь-який момент).

  1. Архітектура мікропослуг добре поєднується з дизайном, керованим доменом. Зазвичай одна MS представляє один обмежений контекст.
  2. Якщо мікросервіс A вимагає функціональності, який знаходиться в мікросервісі B , моя модель, ймовірно, помиляється, і A і B насправді повинні бути однією мікропослугою / BC.
  3. Синхронний зв’язок між мікропослугами (прямі запити HTTP) поганий, тому що він не відповідає меті мікропослуг та вводить з'єднання між компонентами.
  4. Бажано асинхронний зв’язок між службами. Служби повинні публікувати події до черг повідомлень, щоб інші служби могли передплатити та обробити свою частину події або використовувати її для копіювання частини даних, необхідної для їх контексту. Таким чином, сервіси можуть обробляти запити, навіть інші сервіси не працюють, що не було б у випадку синхронного зв'язку.
  5. Якщо мікропослуга A публікує подію, мікропослуга B підписується на цю подію і створює нову подію як результат, мікропослуга A не повинна бути однією, що обробляє новостворену подію, тому що це буде кругова залежність. У цьому випадку ми повинні запровадити третю мікропослугу або поєднати A і B в мікросервісі AB .
  6. Мікросервіс - це фактично оманливий термін. Ми повинні прагнути до малих контекстів, але це не потрібно. Термін не повинен бути "мікропослугою", а " достатньо великим, щоб зробити службу роботи ".
  7. Мікросервіси дозволяють нам з легкістю та без побоювання вводити нові функції у всі нові системи. Це можна зробити, ввівши нову послугу або переробляючи один із існуючих.
  8. Кожна мікросервіс повинна мати власне сховище даних. Реплікація / дублювання даних є бажаною поведінкою в цій архітектурі.

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

Служби не повинні мати ніяких знань про інші сервіси в системі. Вони лише усвідомлюють свій контекст та події, які вони повинні публікувати чи передплачувати?

Відповіді:


4

Ваші висновки здаються в основному обґрунтованими і дуже красиво підсумовують шлях проходження мікросервісів.

Однак я не повністю підтримую 2, 5 і 8:

  • 2) Проста залежність не повинна автоматично призводити до злиття. Ви повинні враховувати частоту таких залежних дзвінків, а також частоту дзвінків від інших служб.

    Отже, якщо мікросервіс A вимагає функціональності в мікросервісі B дуже часто, а мікросервіс B рідко потрібен іншим мікросервісам, вам слід оскаржити передбачувану структуру і запитати, чи не було б більш доцільним групувати обидва мікросервіси.

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

    Але додавання посередника не завадить цьому: A може запустити повідомлення, яке обробляє C, який запускає повідомлення, оброблене B, який запускає повідомлення, оброблене A, і тут ви потрапляєте в петлю.

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

  • 8) так, для кожної мікросервісу має своє спеціальне сховище / базу даних.

    Мінімальна копія потрібна для того, щоб сервіси могли бути незалежними. Однак я б не пішов так далеко, щоб сказати, що потрібна реплікація: вона повинна бути зведена до мінімуму, щоб уникнути прихованої зв'язку через процеси реплікації.

    Мікросервіси стосуються нещільного з’єднання. Іноді це може бути ефективніше досягти, зателефонувавши до іншого мікросервісу для отримання пов'язаних даних замість реплікації даних.

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


"Іноді це може бути більш ефективно досягти, зателефонувавши до іншого мікросервісу для отримання пов’язаних даних, замість реплікації даних" Отже, немає нічого поганого в тому, щоб трохи синхронізувати зв’язок та прямі дзвінки (через HTTP) отримати частину даних, як доки цей запит не представляє розподілену транзакцію / команду, інакше ми не можемо гарантувати атомність цієї команди?
Роберт

1
Тут немає ідеального рішення: це нещільне з'єднання та інкапсуляція ( microservices.io/patterns/data/database-per-service.html ), щоб збалансувати легкість, але надмірність ( microservices.io/patterns/data/event-driven-architecture .html ) у контексті загальної картини ( microservices.io/patterns/microservices.html )
Крістоф

3

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

Служби не повинні мати ніяких знань про інші сервіси в системі. Вони лише усвідомлюють свій контекст та події, які вони повинні публікувати чи передплачувати?

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

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

Щоб відповісти на це питання, спочатку дайте відповідь на це: чому ви хочете спілкуватися асинхронно? Це полегшити самостійну розробку окремих компонентів? Чи варто покращити експлуатаційну доступність для системи 24/7? Скажімо, це останнє, і ви хочете використовувати черги для копіювання даних у локальні бази даних. Ну, тепер ваші дані можуть бути несвіжими. У якийсь момент це буде занадто устареним. Як ви впораєтеся з цим? Більше того, як ви забезпечуєте оперативну доступність черги, що є ще одним компонентом часу виконання? І як ви забезпечите доступність цих локальних баз даних? Замість управління одним кластером баз даних тепер у вас є кілька. Чи може ваша команда ops впоратися з цим навантаженням? І справді, чи варто того складности, коли, можливо, ваші користувачі будуть щасливішими з більшою кількістю функцій та кількома годинами простою щомісяця, якби ви побудували простий моноліт?

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


2
  1. Архітектура мікропослуг добре поєднується з дизайном, керованим доменом. Зазвичай одна MS представляє один обмежений контекст.

Не згоден. DDD, як правило, дуже OO. замовлення доставлено? Order.Deliver (), тоді як мікро-сервіси матимуть DeliveryService.Deliver (замовлення)

  1. Якщо мікросервіс A вимагає функціональності, який знаходиться в мікросервісі B, моя модель, ймовірно, помиляється, і A і B насправді повинні бути однією мікропослугою / BC.

Не погоджуючись, ви повинні спробувати утримати мікро-сервіси мікро. розділіть їх ще менше!

  1. Синхронний зв’язок між мікропослугами (прямі запити HTTP) поганий, тому що він не відповідає меті мікропослуг та вводить з'єднання між компонентами.

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

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

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

  1. Якщо мікропослуга A публікує подію, мікросервіс B підписується на цю подію і створює нову подію як результат, мікропослуга A не повинна бути однією, що обробляє новостворену подію, тому що це буде кругова залежність. У цьому випадку ми повинні запровадити третю мікропослугу або об'єднати A і B в мікросервіс AB.

Не згоден. Це не кругла залежність, оскільки ваші мікро-послуги не пов'язані між собою. Також ви хочете задовольнити повторне використання сенаріонів, SendEmail, EmailFailed, SendAgain не потребує 3 мікро-послуг

  1. Мікросервіс - це фактично оманливий термін. Ми повинні прагнути до малих контекстів, але це не потрібно. Термін не повинен бути "мікропослугою", а "достатньо великим, щоб зробити службу роботи".

Не згоден. Ознайомтеся з нано-сервісами.

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

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

  1. Кожна мікросервіс повинна мати власне сховище даних. Реплікація / дублювання даних є бажаною поведінкою в цій архітектурі.

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


1

Ваші висновки є хорошими правилами, але не універсальними. Будуть випадки, коли найкращим варіантом є порушення цих правил, навіть у проекті «зеленого поля». У деяких випадках найкращим варіантом є синхронне спілкування. У деяких випадках об'єднати два сервіси в одну навіть недобре, навіть якщо вони з'єднані синхронним зв’язком.

Що стосується іншого вашого питання, для спілкування на основі черги не потрібно виявлення сервісу.


0

Гм, ви просто говорите про об'єктно-орієнтоване програмування. Або, принаймні, тим, що спочатку було задумано: незалежні фрагменти запущеного коду, що спілкуються один з одним за допомогою повідомлень.

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

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

Наприклад, майже все, що сказано в інших відповідях, - це висловлювання підручника про ООП.


0

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

Мені було надзвичайно вигідно думати про піддомени як про бізнес-можливості. Бізнес-спроможність - це те, що робить ваша організація. Це одна з його бізнес-функцій. Оскільки наша мета - узгодження бізнесу та ІТ , я, безумовно, хочу, щоб вони мали відношення 1: 1 до моїх технічних служб .

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.