Рубріки: Досвід

Міграція з HTTP API на GRPC: мої «за» та «проти» на власному досвіді роботи над проєктом

Ігор Закутинський

Привіт! Мене звати Ігор Закутинський, я Head of Engineering GetProspect — українського інструменту лідогенерації, що дозволяє знаходити тисячі імейлів у LinkedIn за декілька кліків.

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

Короткий огляд платформи для лідогенерації GetProspect

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

  • Google Chrome extension;
  • CSV-файл;
  • через API;
  • інтеграції зі сторонніми сервісами (наприклад Zapier);
  • Google-таблиці.

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

Чому ми використовуємо мікросервіси?

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

GetProspect реалізований по класичній мікросервісній архітектурі, де кожен мікросервіс відповідає таким критеріям:

  • фокус на конкретні бізнес-задачі;
  • незалежність від мови програмування та фреймворків;
  • простота тестування;
  • розгортання та деплоймент конкретного сервісу не має залежати від інших сервісів.

Мікросервісна комунікація

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

Наші мікросервіси використовують HTTP RESTfull API, як базовий протокол обміну даних. 

REST (Representational State Transfer) — це архітектурний стиль взаємодії розподілених компонентів в мережі.

Основні переваги REST API і чому ми його використовуємо:

  • інтуїтивно зрозумілий;
  • простий у масштабуванні;
  • простий у підтримці та відладці;
  • структура API не залежить від технології та мови програмування.

HTTP REST API задовольняє основні потреби обміну даних між мікросервісами, але через конструктивні особливості не може використоуватись у всіх випадках.

Одним з основних завдань нашого інструменту лідогенерації є пошук імейлу користувача. Пошук електронної пошти базується на SMTP-діалозі з email-сервером та може тривати від кількох секунд до 10 хвилин. 

SMTP (Simple Mail Transfer Protocol) — це комунікаційний протокол для пересилання електронної пошти.

Процес пошуку та валідації email-адрес реалізований на окремому мікросервісі — Mail verification service, а логіка збереження та управління даними на API service

На першому етапі реалізація мала наступний вигляд:

Початкова схема реалізації (натисніть, щоб роздивитися)

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

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

Тобто для того, щоб знайти email-адресу виконувалось як мінімум два HTTP-запити (насправді їх було дещо більше 😉), що породжувало декілька проблем:

  • По-перше, вплив на швидкість та продуктивність. Кожен HTTP-запит ініціює нове клієнт-сервер-з’єднання, що створює велике навантаження.
  • По-друге, це те, що запити не мали спільного контексту, оскільки в REST-архітектурі відсутнє збереження стану запиту (stateless), тобто сервер виконує кожен клієнтський запит не залежно від попередніх.

В якості оптимізації ми розглянули використання GRPC для комунікації цих двох мікросервісів, оскільки в ньому архітектурно вирішені недоліки, про які я писав вище.  

Що таке GRPC? Чому ми його обрали для мікросервісної комунікації?

GRPC це сучасний протокол RPC, реалізований зверху HTTP/2.

HTTP/2  — це протокол рівня 7 (рівень додатків), який працює зверху протоколу TCP (рівень 4 — транспортний рівень), який працює зверху протоколу IP (рівень 3 — мережевий рівень). 

GRPC має багато переваг традиційним HTTP/REST/JSON, наприклад:

  • двійковий протокол (HTTP/2);
  • мультиплексування багатьох запитів на одному з’єднанні (HTTP/2);
  • стиснення заголовку (HTTP/2);
  • суворо типізований сервіс і повідомлення (Protobuf);
  • серіалізація/десеріалізація даних.

Повідомлення GRPC серіалізуються за допомогою Protobuf — ефективного двійкового формату повідомлень. Protobuf дуже швидко виконує серіалізацію на сервері та клієнті. 

Protobuf швидко виконує серіалізацію на сервері та клієнті

За допомогою Protobuf-серіалізації нам вдалось значно зменшити об’єм корисних даних, а отже збільшити пропускну здатність між API-сервісом та сервісом, який процесить пошук email-адрес. Також значно спростилась логіка пошуку. На боці API service процес пошуку імейла виглядає як виклик асинхронної функції (віддаленої процедури у випадку з gRPC 😉).

Тест продуктивності: GRPC vs HTTP Restful API

Я вирішив провести тест, для якого використовував два AWS EC2 c5.2xLarge instance, на яких були запущені Node.js application — клієнт та сервер.

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

gRPC server, який використовувався для тесту:

Натисніть, щоб роздивитися

gRPC client, який використовувався для тесту:

Натисніть, щоб роздивитися

Для тесту HTTP Rest API реалізована аналогічна логіка на Fastify та Axios.  

Результати тесту:

HTTP Post request gRPC procedure call
100k async requests, sec 32.342 4.370
Requests per second 2147 26102
CPU usage – ms/req 491 ms / per request 211 ms / per request

Як видно з графіку, пропускна здатність GRPC більш ніж у вісім разів вища за HTTP API, що значно підвищує продуктивність на великих об’ємах запитів. Також слід відмітити те, що CPU час на 1 gRPC процедуру більш ніж в два рази менший, ніж на аналогічний HTTP-запит. 

Балансування навантаження

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

Існує два основних підходи до GRPC-балансування: 

  • на боці клієнта;
  • балансування через proxy-сервер.

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

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

Ці проблеми значно ускладнюються при зростанні кількості клієнтів.

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

Балансування через Haproxy / Натисніть, щоб роздивитися

Безпека в GRPC-мікросервісах

GRPC підтримує SSL/TLS encryption, що дозволяє шифрувати дані, якими обмінюється клієнт та сервер. Також GRPC надає простий Auth API, який дозволяє надати авторизаційні дані під час створення каналу або виклику функції.

Приклад авторизації через SSL/TLS сертифікати:

const cert = fs.readFileSync('path/to/cert');

const ssl = grpc.credentials.createSsl(cert);

const stub = new service.Verification('grpc.service.com', ssl);

Слабкі сторони GRPC

Браузерна підтримка

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

Недоступний для читання людиною

Запити HTTP Rest API відправляються в текстовому вигляді (JSON), що дозволяє розробникам їх легко читати та редагувати. gRPC використовує двійковий протокол Protobuf, що є значно ефективнішим, але не читається людиною, що ускладнює та сповільнює процес відладки та розробки.

Висновки

На сьогодні GRPC є перспективним рішенням для мікросервісів, де необхідна висока пропускна здатність. Його використання дозволило нам опимізувати bottleneck нашої системи, там значно скоротити витрати на трафік та збільшити продуктивність. 

Тим не менш, через складність в реалізації, а також відсутність повноціної браузерної підтримки ми не можемо розглядати GRPC як повноціного конкурента HTTP REST API. 

Діліться вашими думками, чи мігрували ви з HTTP API на GRPC, і якими були результати?

Якщо ви знайшли помилку, будь ласка, виділіть фрагмент тексту та натисніть Ctrl+Enter.

Останні статті

IT в Україні йде до свого фінального кінця. І потраплятимуть туди виключно за покликом душі

Коротко про українську IT-сферу у 2024 році Це коли на одну вакансію Middle розробника по…

26.03.2024

Блокчейн-розробка сьогодні: зарплати і перспективи на ринку праці

Формування криптовалютної галузі в Україні почалося ще у 2014 – саме тоді з'явилися перші стартапи,…

18.03.2024

Скільки рішень ухвалює розробник? Погляд новачка, який запускає продукт

Автор цього блогу — Python-девелопер Сергій Солдатов, який вирішив створити досить унікальний продукт. І це…

12.03.2024

Чи треба готуватись до співбесіди?

Думки шукачів діляться на: «так, однозначно» і «ні, не вартує, я все і так про…

04.03.2024

Відкладаєте до останнього? Що таке «синдром студента» і як з ним боротися

Синдром студента — це форма прокрастинації, яка полягає в тому, що людина, якій дали завдання,…

23.02.2024

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

Git — це найпопулярніша CVS прямо зараз, яка дозволяє відстежувати історію розробки і спільно працювати.…

20.02.2024