a.akhunov 26 марта 2021

🕸 gRPC и все-все-все: Часть I. Введение

Для лучшего понимания gRPC стоит разобраться и с другими протоколами. В первой части цикла мы поговорим о REST, RPC и затронем одну из его реализаций – SOAP.
Все сущее движется, и ничто не остается на месте.
Гераклит Эфесский, в изложении Платона (диалог «Кратил»)
Картинку позаимствовал с одной моей любимой книги. Она сюда подходит. Как мне кажется ;)
Картинку позаимствовал с одной моей любимой книги. Она сюда подходит. Как мне кажется ;)

Форматы кодирования данных

Программы обычно имеют дело с данными в (как минимум) двух представлениях:

  1. В памяти данные хранятся в объектах, структурах, списках, массивах, хэш-таблицах, деревьях и т.д. Эти структуры данных оптимизированы так, чтобы CPU мог эффективно обращаться к ним и манипулировать ими.
  2. При необходимости записать данные в файлы или переслать их по сети необходимо кодировать их в некую самостоятельную последовательность байтов (например, документ в формате JSON). Такое представление в виде последовательности байтов выглядит совсем не так, как обычные структуры данных в памяти.

Следовательно, нам нужен способ преобразования между этими представлениями. Преобразование из представления в памяти последовательность байтов называется кодированием(encoding), или сериализацией(serialization), или маршалингом(marshalling), а обратная ему операция – декодированием (decoding), или парсингом(parsing), или десериализацией(deserialization), или демаршалингом(demarshalling).

Тут очевидными претендентами являются JSON и XML. Они довольно известны, широко поддерживаются, и их практически столь же активно недолюбливают. XML часто критикуют за его «многословность» и излишнюю усложненность. JSON обязан своей популярностью в основном встроенной поддержке в браузерах и относительной простоте по сравнению с XML. CSV – еще один популярный и независимый от языка программирования формат, хотя и обладающий меньшими возможностями. JSON, XML и CSV – текстовые форматы, а значит, в какой-то мере удобочитаемые для людей.

REST и RPC

SOAP vs REST
SOAP vs REST

Существует несколько различных способов организации взаимодействия процессов по сети:

REST – это не протокол, а скорее подход к проектированию, основанный на принципах HTTP (предыдущей моя статья про HTTP https://proglib.io/p/chto-takoe-http-i-https-2021-03-22). Он делает акцент на простых форматах данных, применении URL для идентификации ресурсов и использовании возможностей HTTP для управления кэшем, аутентификации и согласования типа контента. API, спроектированный в соответствии с принципами REST, называют воплощающим REST (RESTful).

RPC(Remote Procedure Call) – класс технологий, позволяющих программам вызывать функции или процедуры в другом представлении или в адресном пространстве (на удалённых узлах, либо в независимой сторонней системе на том же узле). Одной из его реализаций является SOAP. SOAP – это основанный на формате XML протокол для выполнения запросов к сетевым API. Будучи применяемым чаще всего по HTTP, он стремится к независимости от последнего и избегает использования большинства его возможностей. Вместо этого к нему прилагается масса разнообразных сопутствующих стандартов (фреймворк веб-сервисов, известный под названием WS-*), которые добавляют в него различные возможности. API SOAP веб-сервиса описывается с помощью основанного на XML языка, именуемого языком описания веб-сервисов (Web Services Description Language, WSDL). Первоначально SOAP предназначался в основном для реализации удалённого вызова процедур RPC.

REST более популярен по сравнению с SOAP, по крайней мере в контексте интеграции сервисов между организациями, и часто ассоциируется с микросервисами.

gRPC

gRPC – это новый и современный фреймворк для разработки масштабируемых, современных и быстрых API и дословно переводится как система удаленного вызова процедур, разработанный компанией Google еще в далеком 2015 году (https://developers.googleblog.com/2015/02/introducing-grpc-new-open-source-http2.html). Используется многими ведущими компаниями, такими как Google, Square и Netflix, и позволяет программистам писать микросервисы на любом языке, который они хотят, сохраняя при этом возможность легко устанавливать связь между этими сервисами. И так же является реализацией удалённого вызова процедур (RPC), но уже в качестве транспорта использует новый (не побоюсь сказать модный) HTTP/2 (https://http2.github.io/).

оставлю ссылку где можно будет поиграться и увидеть разницу в производительности между HTTP2 и HTTP1.1

А для описания интерфейса используется Protocol Buffers (protobuf), где описывается структура для передачи, кодирования и обмена данных между представлениями описанными выше. Protocol Buffers проще, компактнее и быстрее, чем XML, поскольку осуществляется передача бинарных данных.

Попробуем разобраться во всем всем этом!

Описание Protocol Buffers (protobuf) выглядит примерно так:

calculator.proto
        // Синтакс для данного файла proto3
syntax = "proto3";

/* Наименование пакета данных */
message Calculator {
    int32 xxx = 1;
    int32 yyy = 2;
}

message CalculatorRequest {
    Calculator calculator = 1;
}

message CalculatorResponse {
    int32 result = 1;
}

/* Наименование сервиса, который будет осуществлять
 калькуляцию данных полей xxx и yyy
*/
service CalculatorService {
    rpc Calculator(CalculatorRequest) returns (CalculatorResponse) {};
}

    

Все очень просто, неправда ли? (во второй части статьи расскажем про protobuf подробнее и покажем как и с чем его есть и применим на практике, напишем свой собственный сервис).

Какие бывают разновидности API в gRPC?

Унарный (Unary) – синхронный запрос клиента, который блокируются пока не будет получен ответ от сервера.

<i>Унарный (Unary)</i>
Унарный (Unary)

Потоковая передача сервера (Server streaming) – при подключении клиента сервер открывает стрим и начинает отправлять сообщения.

<i>Потоковая передача сервера (Server streaming)</i>
Потоковая передача сервера (Server streaming)

Потоковая передача клиента (Client streaming) – то же самое, что и серверный, только клиент начинает стримить сообщения на сервер.

<i>Потоковая передача клиента (Client streaming)</i>
Потоковая передача клиента (Client streaming)

Двунаправленная потоковая передача (Bi-directional streaming) – клиент инициализирует соединение, создаются два стрима. Сервер может отправить изначальные данные при подключении или отвечать на каждый запрос клиента по типу “пинг-понга”

<i>Двунаправленная потоковая передача (Bi-directional streaming)</i>
Двунаправленная потоковая передача (Bi-directional streaming)

Балансировка нагрузки (Load Balancing) в gRPC

Балансировка нагрузки между сервисами работающих между собой по gRPC выполняется на стороне клиента. В данном случае клиент использует простой “round-robin” алгоритм для передачи запросов по списку полученному от LB (LoadBalancing) сервера. При желании на стороне LB сервера можно организовать более сложный алгоритм выдачи списка бэкенд сервисов клиенту использую LB политики.

io.grpc.LoadBalancerProvider
        io.grpc.internal.PickFirstLoadBalancerProvider
io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider

    
Схема осуществления и распределения нагрузки в gRPC
Схема осуществления и распределения нагрузки в gRPC
***

На этом пока все) Начну готовить вторую часть цикла, где хочу показать на практике разработку такого удивительного сервиса, а в дальнейшем мы постараемся нагрузить его!

Будет интересно ;-) Оставайтесь с нами!

Это моя вторая статья для proglib.io и я буду очень рад, если вы оцените ее, поставив лайк или написав комментарий.

Ахунов Азат

Дополнительные материалы по теме:

МЕРОПРИЯТИЯ

Комментарии 0

ВАКАНСИИ

C++ Toolset Developer возможен Remote
по итогам собеседования
Middle Full Stack-разработчик
от 140000 RUB до 170000 RUB
Data Engineer
от 200000 RUB до 300000 RUB

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

Microsoft