Все сущее движется, и ничто не остается на месте. Гераклит Эфесский, в изложении Платона (диалог «Кратил»)
Картинку позаимствовал с одной моей любимой книги. Она сюда подходит. Как мне кажется 😉
Форматы кодирования данных
Программы обычно имеют дело с данными в (как минимум) двух представлениях:
В памяти данные хранятся в объектах , структурах , списках , массивах , хэш-таблицах , деревьях и т.д. Эти структуры данных оптимизированы так, чтобы CPU мог эффективно обращаться к ним и манипулировать ими.
При необходимости записать данные в файлы или переслать их по сети необходимо кодировать их в некую самостоятельную последовательность байтов (например, документ в формате JSON ). Такое представление в виде последовательности байтов выглядит совсем не так, как обычные структуры данных в памяти.
Следовательно, нам нужен способ преобразования между этими представлениями. Преобразование из представления в памяти последовательность байтов называется кодированием (encoding ), или сериализацией (serialization ), или маршалингом (marshalling ), а обратная ему операция – декодированием (decoding ), или парсингом (parsing ), или десериализацией (deserialization ), или демаршалингом (demarshalling ).
Тут очевидными претендентами являются JSON и XML . Они довольно известны, широко поддерживаются, и их практически столь же активно недолюбливают. XML часто критикуют за его «многословность » и излишнюю усложненность. JSON обязан своей популярностью в основном встроенной поддержке в браузерах и относительной простоте по сравнению с XML . CSV – еще один популярный и независимый от языка программирования формат, хотя и обладающий меньшими возможностями. JSON , XML и CSV – текстовые форматы, а значит, в какой-то мере удобочитаемые для людей.
REST и RPC
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 https://imagekit.io/demo/http2-vs-http1
А для описания интерфейса используется 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) – синхронный запрос клиента, который блокируются пока не будет получен ответ от сервера.
Унарный (Unary)
Потоковая передача сервера (Server streaming) – при подключении клиента сервер открывает стрим и начинает отправлять сообщения.
Потоковая передача сервера (Server streaming)
Потоковая передача клиента (Client streaming) – то же самое, что и серверный, только клиент начинает стримить сообщения на сервер.
Потоковая передача клиента (Client streaming)
Двунаправленная потоковая передача (Bi-directional streaming) – клиент инициализирует соединение, создаются два стрима. Сервер может отправить изначальные данные при подключении или отвечать на каждый запрос клиента по типу “пинг-понга”
Двунаправленная потоковая передача (Bi-directional streaming)
Балансировка нагрузки (Load Balancing) в gRPC
Балансировка нагрузки между сервисами работающих между собой по gRPC выполняется на стороне клиента. В данном случае клиент использует простой “round-robin” алгоритм для передачи запросов по списку полученному от LB (L oadB alancing ) сервера. При желании на стороне LB сервера можно организовать более сложный алгоритм выдачи списка бэкенд сервисов клиенту использую LB политики.
io.grpc.LoadBalancerProvider
io.grpc.internal.PickFirstLoadBalancerProvider io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider
Схема осуществления и распределения нагрузки в gRPC ***
На этом пока все) Начну готовить вторую часть цикла, где хочу показать на практике разработку такого удивительного сервиса, а в дальнейшем мы постараемся нагрузить его!
Будет интересно 😉 Оставайтесь с нами!
Это моя вторая статья для proglib.io и я буду очень рад, если вы оцените ее, поставив лайк или написав комментарий.
Ахунов Азат
Дополнительные материалы по теме:
Микросервисная архитектура на примере Python и gRPC.