Як архітектури мікросервісних систем уникають вузьких вузьких місць?


72

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

Для точності, ось мої інтерпретації двох термінів:

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

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

На мою наївну уяву, схоже, що архітектура мікросервісів використовує повільний мережевий трафік на відміну від швидших ресурсів на одній машині (пам'ять та диск). Як можна гарантувати, що запит API через внутрішню мережу не сповільнить загальний час відповіді?


Внутрішня мережа часто 1 Гбіт / с, іноді швидша. Подумайте про середній розмір відповіді JSON від API. Скільки таких відповідей може бути передано за 1 Гбіт / с за одну секунду?
Арсеній Муренко

3
якщо ви думаєте, що вам потрібні мікросервіси - і ви можете! - дві чудові книги для підготовки: amazon.com/Building-Microservices-Sam-Newman/dp/1491950358 та amazon.com/Release-It-Production-Ready-Pragmatic-Programmers/dp/…
Стівен А. Лоу

@MainMa проблема не в пропускній здатності, а в затримці. І якщо вам потрібно повернути назад, ви здивуєтеся, якою реальною пропускною здатністю ви можете скористатися
Stephan Eggermont

Відповіді:


61

Внутрішні мережі часто використовують з'єднання 1 Гбіт / с або швидше. Оптичні волокна або з'єднання дозволяють значно збільшити пропускну здатність між серверами. Тепер уявімо середній розмір відповіді JSON від API. Скільки таких відповідей може бути передано за 1 Гбіт / с за одну секунду?

Давайте насправді зробимо математику. 1 Гбіт / с - 131 072 Кб в секунду. Якщо середня відповідь JSON становить 5 Кб (що досить багато!), Ви можете надсилати 26 214 відповідей в секунду по дроту лише за допомогою однієї пари машин . Не так вже й погано, чи не так?

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

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

Це коли наші попередні 26 214 відповідей в секунду стають занадто малими для масштабу програми. Ви додаєте ще дев'ять пар, і тепер ви можете надіслати 262 140 відповідей.

Але повернемося до нашої пари серверів і зробимо кілька порівнянь.

  • Якщо середній некешований запит до бази даних займає 10 мс., Ви обмежені 100 запитами в секунду. 100 запитів. 26 214 відповідей. Досягнення швидкості 26 214 відповідей в секунду вимагає великої кількості кешування та оптимізації (якщо відповідь насправді потребує чогось корисного, наприклад запиту в базу даних; відповіді в стилі "Hello World" не кваліфікуються).

  • На моєму комп’ютері зараз DOMContentLoaded для домашньої сторінки Google сталося 394 мс. після надсилання запиту Це менше 3 запитів в секунду. Для домашньої сторінки Programmers.SE це сталося 603 мс. після надсилання запиту Це навіть не 2 запити в секунду. До речі, у мене є інтернет-з'єднання зі швидкістю 100 Мбіт / с і швидкий комп'ютер: багато користувачів будуть чекати довше.

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

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

Подумайте про бази даних

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

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

Коли швидкість передачі насправді має значення, коли компанія розміщує великі набори даних у NAS, а до NAS доступні декілька клієнтів одночасно. Тут SAN може бути рішенням. Це, як говориться, не єдине рішення. Кабелі Cat 6 можуть підтримувати швидкість до 10 Гбіт / с; приєднання також може використовуватися для збільшення швидкості без зміни кабелів або мережевих адаптерів. Існують й інші рішення, що включають реплікацію даних через декілька NAS.

Забудьте про швидкість; подумайте про масштабованість

Важливим моментом веб-програми є можливість масштабування. Хоча фактичні показники мають значення (оскільки ніхто не хоче платити за більш потужні сервери), масштабованість набагато важливіша, оскільки вона дозволяє вам кидати додаткове обладнання при необхідності.

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

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

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

Незважаючи на втрату продуктивності, віртуальні середовища стали дуже популярними через гнучкість, яку вони надають.

Як і у випадку швидкості мережі, ви можете виявити, що VM - це фактичне вузьке місце і враховуючи фактичний масштаб, ви заощадите мільярди доларів, розмістивши програму безпосередньо, без віртуальних машин. Але це не те, що трапляється для 99,9% додатків: їх вузьке місце знаходиться десь в іншому місці, і недолік втрати на кілька мікросекунд через VM легко компенсується вигодами апаратної абстракції та масштабованості.


Звичайно, можна сказати, що відповіді JSON невеликі, але як щодо їх кількості ? Я відчуваю, що веб-сайт під великим навантаженням матиме більше мережевого трафіку в архітектурі мікросервісу, ніж монолітної архітектури (де єдиний мережевий трафік - до / з сервера (ів) баз даних). Кешування може допомогти, але в режимі реального часу та / або динамічно створеного контенту я не знаю, наскільки далеко піде кешування.
Джеймс Мішра

@JamesMishra: Я змінив свою відповідь, щоб вирішити ваші проблеми.
Арсеній Мурценко

Ваша відповідь ідеальна . Ви не тільки відповідали на всі заперечення, які я можу придумати, ви відповідали на заперечення, про які я не думав.
Джеймс Мішра

5
Мої 2 центи з реального світу: Система, що складається з дуже балакучих мікросервісів, може зазнати проблем з продуктивністю виключно через задушену мережу. У таких випадках ваш друг - це кешування та дизайн подій Stream. Окрім мережі, процесора та пам'яті, система, що базується на мікросервісі, також повинна включати стійкість у свою конструкцію: що станеться, якщо мікросервіс не працює? Як ви створюєте спроби, розподілені транзакції, самолікування, моніторинг - я пропоную шукати "ви повинні бути таким високим, щоб користуватися мікросервісами"
Sudhanshu Mishra

4
Будь ласка, виправте мене, якщо я помиляюся, але, наскільки я знаю, якщо у вас є мережа 1Gbps, це означає, що ви можете теоретично надсилати дані вартістю 1 Гбіт в секунду через цю мережу. Незалежно від кількості підключень. Чим більша кількість з'єднань, тим менша пропускна здатність для кожного з'єднання. Таким чином, ваш фактичний ліміт без оновлення мережі для підтримки більшої пропускної здатності складе 26,214 відповідей в секунду. Додавання більше серверів не збільшить пропускну здатність вашої мережі. Якщо один кластер може витратити цю кількість трафіку, додавання більшої кількості серверів, що генерують ще більше даних, призведе до обертання вашої мережі.
Sebbe

7

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


3
"Служби не розмовлятимуть між собою." Я думаю, що мікросервіси можуть мати спільні залежності (можливо, автентифікація?), Які можна розділити на іншу мікросервіс. LDAP, в певному сенсі, є мікросервісом аутентифікації, і я думаю, що всі інші мікросервіси розмовляють з ним. Або ... чи автентифікація відбувається лише один раз? Як кожна мікросервіс перевіряє дозволи на аутентифікацію, щоб запобігти атакам прямого об’єктного доступу?
Джеймс Мішра

2
@JamesMishra добре .. це залежить. Коли я востаннє використовував архітектуру мікросервісу, кожна послуга була цілком незалежною від інших з метою безпеки (але також і з корпоративних причин силосу). Auth кожен обробляв по-різному, хоча й контролювався архітектурною політикою. Тим не менш, немає причин, щоб вони не могли поговорити з автором, наприклад, або просто мати автентифікацію на основі бібліотеки. Але .. Я намагався сказати, що вони не повинні передавати багато дзвінків між собою, не те, що вони не повинні споживати послуги як самі клієнти.
gbjbaanb

@JamesMishra, auth часто є власним сервісом у цих середовищах, і тому кожна служба повинна просто використовувати це, а не робити повну реалізацію самостійно.
Павло

2

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


Приклад для пояснення того, що я вважаю, що означає @mortalapeman: у вас є java / c # інтерфейс IProductAvailibitiy, де всі споживачі IProductAvailibitiy пов'язані проти. Існує також клас ProductAvailibitiyImpl, який реалізує цей інтерфейс, і продукт ProductAvailibitiyMicroservice, який використовує ProductAvailibitiyImpl. Споживачі можуть бути налаштовані для використання або локального ProductAvailibitiyImpl, або віддаленого проксі для ProductAvailibitiyMicroservice
k3b

2

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

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

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

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

Думайте дуже уважно про те, як працюють сервіси, коли їм дзвонять і якими даними обмінюються. Наші програми вже не обмінюються просто інформацією про позицію, вони обмінюються інформацією про мертвий розрахунок - я перебуваю в позиції x, прямуючи у напрямку y зі швидкістю q. І мені не потрібно оновлювати свою інформацію, поки ці припущення не зміниться. Набагато менше оновлень і затримка (хоча це все-таки проблема) з'являється пропорційно рідше.

Тому замість того, щоб запитувати послугу з дрібним зерном на більш високій частоті, спробуйте знизити частоту на:

  1. змінюючи дані, які запитуються, та використовувати локальні обчислення
  2. надсилання параметрів запиту або тригера для асинхронної відповіді
  3. пакетні запити
  4. передбачення запитів та підготовка відповіді заздалегідь, на спекуляції (навпроти ледачої оцінки)
  5. де це можливо, уникайте мікросервісів, які викликають інші мікросервіси; очевидно, це поєднує проблему. Я розумію, що це стимул до збільшення мікросервісів і дещо перемагає точку, але мікросервіси не є другом за затримкою. Можливо, просто визнай це і переборюй.

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


1

Ваша наївна уява права. І часто це не має значення. Сучасні машини швидкі. Основні переваги архітектури мікросервісу вбачаються у зусиллях на розробку та обслуговування та час.

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


Процесори швидкі. Пам'ять швидко. SSD-файли швидкі. Але чи є мережеві карти та маршрутизатори та комутатори "швидкими"? Ще одна відповідь наполягає на цьому, але я не впевнений.
Джеймс Мішра

Напевно, легко зіткнутися з проблемами швидкості мережі. Запустіть одну службу в Сан-Франциско, іншу в Амстердамі та споживайте їх у Сіднеї. Затримка - це ключ, а не пропускна здатність. Тож не робіть цього. І зробіть сервіси настільки великими, наскільки це має сенс
Стефан Еггермон

1

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

Спосіб досягнення цієї користі - це спочатку визначити свої бізнес-можливості. Бізнес-спроможність - це специфічна відповідальність за бізнес. Деякий внесок у загальну цінність для бізнесу. Отже, ось моя послідовність кроків, яку я приймаю, коли замислююся про межі системи:

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

Майте на увазі, що бізнес-сервіс включає людей, додатки, бізнес-процеси. Зазвичай лише частина його представлена ​​як технічна влада.

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


0

Ще один фактор, який слід додати до поточних відповідей. З грубозернистими послугами . Ви хочете уникнути затримки всіх дзвінків, тому замість того, щоб робити 10 дзвінків, ви здійснюєте дзвінок, який отримує 10 даних, необхідних у DTO.

І пам’ятайте, що мікросервіси не такі мікро, як люди думають.

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