Как мы используем микросервисы и GRPC

27 марта 2020
1115
Linux
GRPC

Предисловие

Наш основной бизнес — хостинг. Чтобы пользователям было удобно работать с хостингом, нужно предоставить им панель управления.

Так сложилось, что мы не взяли готовую панель управления для хостинга, а выбрали более сложный путь — решили сделать панель управления сами. Постепенно в нее добавлялись биллинг, хелпдеск для технической поддержки, админская панель и много что еще.

Спустя больше 16 лет в проекте накопились десятки тысяч строк кода на Python 2.7. Такие проекты называют монолитом. Вот и у нас получился большой и сложно управляемый монолит

Монолит в фильме "Космическая одиссея 2001 года" (1968)

У нас появилось несколько проблем:

  • Крайне медленная разработка новых фич. Есть множество зависимостей, и новый код может легко сломать старый код.
  • Сложный старт для новых разработчиков. В среднем нужно пол-года разбираться со всем проектом, чтобы начать делать что-то полезное.
  • Скудный набор тестов, нет CI/CD
  • Всё написано на python 2.7, а хотелось 3.8 и/или golang

Чтобы избавиться от этих проблем, с 2017 года мы решили переходить на использование микросервисов.

Хорошо, переходим на микросервисы. Что дальше?

Теперь надо определить как связать между собой микросервисы. Для связи с первым микросервисом мы использовали REST API. Мы взяли Swagger, чтобы стандартизировать и документировать полученное API.

Вот какие минусы этой связки мы обнаружили:

1. В REST нужно придумать все параметры URL микросервиса. Нужно писать стандарты. Мы придумали сначала одну версию стандарта. Оказалось, что продумали не все. Пришлось разработать еще одну версию. А по мере увеличения числа микросервисов наверняка потребовалось бы ее дорабатывать.

2. Чтобы работать с REST API пробовали библиотеку beego для языка Go. Beego выдавал swagger файл, но библиотеки в Python его не понимали.

3. Кроме самого микросервиса нужно было писать код, чтобы наш монолит мог работать с микросервисом. И скорость разработки замедлилась ещё больше.

С REST оказалось не очень удобно. А чем лучше будет GRPC?

  • Нет проблем REST API (привязка к http-методам, статусам и url).
  • Современный HTTP 2 из коробки.
  • Мультиплексирование. Данные загружаются в рамках одного соединения, а не отдельное соединение на каждый ресурс как в HTTP 1.1.
  • Двунаправленная связь. Запросы не только от клиента к серверу, но и наоборот.
  • Поддержка C++, C#, Dart, Java, Python, Golang, Node.js, Ruby, PHP, Objective-C.
  • Авторизация в виде плагинов.

Описание структур в GRPC идет через Protobuf. Что такое Protobuf? Это альтернатива XML, только лучше:

  • Более простой синтаксис
  • От 3 до 10 раз компактнее
  • До 100 раз быстрее обработка файла

Вот как может выглядеть структура Protobuf для описания автомобиля:


message Owner {
    string name = 1;
    string license = 2;
}

enum BodyType {
    sedan = 1;
    hatchback = 2;
}

message Car {
    string model = 1;
    int32 year = 2;

    BodyType type = 3;
    repeated Owner owner = 4;
}

Подробнее о Protobuf на английском языке.

А как отлаживать вызовы в GRPC? Можно ли отправлять curl запросы как в REST?

GRPC — бинарный протокол, поэтому сразу работать с ним как с REST через curl или wget не получится. Но есть расширение, которое называется Rest GRPC Gateway. Он работает как прокси сервер:

Какой вебсервер умеет работать с GRPC?

В nginx начиная с версии 1.13.10 есть поддержка GRPC.

Пример конфига nginx, который проксирует GRPC:

location /helloworld.Greeter {
    grpc_pass grpc://192.168.20.11:50051;
}


location /helloworld.Dispatcher {
    grpc_pass grpc://192.168.20.11:50052;
}

Есть поддержка upstream, значит можно запустить несколько экземпляров микросервиса на разных IP. А nginx станет автоматически балансировать нагрузку между ними.

Если один из экземпляров микросервиса начнет отвечать ошибками, то nginx временно перестанет отправлять на него запросы. Очень удобно.

Собираем все кусочки вместе. GRPC в production

Вот как у нас это работает в "боевом" окружении:

Gateway API делает централизованную авторизацию. Еще он знает в каком микросервисе находится какая бизнес логика.

AGENT - на каждом железном сервере у нас установлена небольшая программа-клиент, которая от микросервисов принимает команды и выполняет их. Раньше к похожим агентам на серверах мы обращались по SSH. Теперь стали обращаться тоже по GRPC.

Какой профит мы получили от GRPC в production?

Приведем пример для одного из сервисов — почты.

У нас десятки тысяч почтовых ящиков и много железных почтовых серверов. Раз в час мы проходимся биллингом по всем серверам и подсчитываем какой ящик сколько занимает места, кто превысил квоту и тд.

Раньше это делал скрипт на Python последовательно обходя все сервера по SSH. И занимало это 15 минут.

Мы переписали скрипт на Golang. Используя возможности Golang, скрипт начал ходить на сервера параллельно. А еще мы изменили транспорт на GRPC. И теперь подсчет занимает 15 секунд. Если убрать подробное логирование в скрипте, то все выполняется вообще за 3 секунды.

Вот какие выводы мы сделали после работы с GRPC:

  • Очень быстрый
  • Сокращает время разработки
  • GRPC отлично подходит для организации взаимодействия микросервисов
  • Более удобный, чем REST
  • Отличная обратная совместимость

Создаем GRPC сервис на примере генератора паролей

Документация GRPC на английском языке.

Рекомендуемые статьи:

Мы используем файлы cookie для предоставления наших услуг, а также для аналитики и маркетинга. Продолжая просматривать наш веб-сайт, вы соглашаетесь на использование нами файлов cookie.
ОК