...

Проектирование gRPC-сервиса

архитектура ИС, проектирование API, gRPC для аналитиков, обучение системных и бизнес-аналитиков, Школа прикладного бизнес-анализа и проектирования информационных систем

В поддержку моего нового курса по архитектуре информационных систем Дизайн API, сегодня я покажу принципы и последовательность проектирования gRPC-сервиса на примере системы работы с поставщиками.

Еще раз о gRPC: краткий ликбез

В последнее время gRPC как технология интеграции информационных систем становится все более популярной. Этот фреймворк и протокол удалённого вызова процедур (Remote Procedure Calls) предложены компанией Google в 2015 году. Одним из главных достоинств gRPC считается скорость, которая обеспечивается благодаря следующим факторам:

  • быстрый протокол HTTP/2 в качестве транспорта данных, который обеспечивает мультиплексирование, более эффективное сжатие заголовков запросов и ответов, а также двунаправленную потоковую передачу;
  • бинарный формат сериализации полезной нагрузки Protocol Buffers (protobuf) со встроенной схемой данных.

С точки зрения разработчика gRPC хорош тем, что поддерживает разные языки программирования, позволяя, например, писать frontend на одной языке, а backend – на другом. Жесткая схема входных данных как параметров функций (процедур), вызываемых на удаленном сервере, а также результатов их обработки, обеспечивает валидацию сообщений и сокращает количество ошибок, связанных с несовпадением типов данных.

С точки зрения клиент-серверной архитектуры, gRPC поддерживает 4 варианта удаленного взаимодействия:

  • унарное в стиле запрос-ответ, когда клиент отправляет серверу один запрос и получает один ответ;
  • потоковое серверное, когда в ответ на запрос клиента сервер начинает потоковую передачу данных (стриминг);
  • потоковое клиентское, когда клиент отправляет на сервер поток запросов и получает один ответ;
  • двунаправленное потоковое, когда клиент и сервер передают друг другу потоки данных в обоих направлениях.

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

Основы архитектуры и интеграции информационных систем

Код курса
OAIS
Ближайшая дата курса
20 января, 2025
Продолжительность
16 ак.часов
Стоимость обучения
36 000 руб.

Проектирование gRPC-сервиса

Вспомнив, что такое gRPC, рассмотрим последовательность проектирования gRPC-сервиса. Как обычно, пойдем от требований. В качестве примера возьмем систему работы с поставщиками, которая должна иметь следующие функции:

  • выдавать информацию о поставщике по его ИНН: название, адрес, телефон, email;
  • принимать поток заказов этому поставщику до тех пор, пока количество единиц товара не превысит определенный лимит, например, 50 единиц. По завершении приема заказов система выдает общую сумму и суммарное количество товарных единиц, отправленных в заказ, а также дату и время окончания приема.

Сформулируем эти требования в виде вариантов использования (ВИ) и покажем на UML-диаграмме Use Case.

UML-диаграмма вариантов использования gRPC-сервиса
UML-диаграмма вариантов использования gRPC-сервиса

Скрипт PlantUML для этой UML-диаграммы Use Case:

@startuml
left to right direction
actor Пользователь as U
rectangle gRPC-сервис {
  usecase "Узнать подробности о поставщике по ИНН" as UC1
  usecase "Отправить заказы поставщику" as UC2
}
U --> UC1
U --> UC2
@enduml

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

UML-диаграмма последовательности по запросу данных о поставщике
UML-диаграмма последовательности по запросу данных о поставщике

Скрипт PlantUML для этой UML-диаграммы последовательности:

@startuml
title UC-1. Узнать подробности о поставщике по ИНН
actor Пользователь as U
participant "gRPC-сервис" as S
U -> S : GetInfoByINN(ProviderINN)
S --> U : ProviderData
@enduml
UML-диаграмма последовательности по отправке заказов поставщику
UML-диаграмма последовательности по отправке заказов поставщику

Скрипт PlantUML для этой UML-диаграммы последовательности:

@startuml
title UC-2. Отправить заказы поставщику
actor Пользователь as U
participant "gRPC-сервис" as S
loop пока суммарное количество товарных единиц менее 50
U -> S : StreamOrders(OrderRequest)
S --> U : OrderResponse
end loop
@enduml

Определим для каждого варианта использования полезную нагрузку запросов и ответов в формате protobuf.

Use Case Запрос Ответ
ВИ Характер Полезная нагрузка Характер Полезная нагрузка
UC-1 Узнать подробности о поставщике по ИНН Пакетный (один запрос) message ProviderINN {

  string inn = 1;

}

Пакетный (один ответ на один запрос) message ProviderData {

  string inn = 1;

  string name = 2;

  string phone = 3;

  string email = 4;

  string address = 5;

}

UC-2 Отправить заказы поставщику Потоковый («бесконечная» отправка запросов) message OrderItem {

    string product = 1;

    int32 quantity = 2;

    double price = 3;

}

message OrderRequest {

  ProviderINN provider = 1;

  repeated OrderItem item = 2;

}

Пакетный (один ответ на поток запросов) message OrderResponse {

    int32 quantity = 1;

    double amount = 2;

    google.protobuf.Timestamp orderdate = 3;

}

 

В полезной нагрузке запросов и ответов, помимо перечисления полей и их типов данных также приведены значения для каждого поля в виде целых числе, начиная с 1. Этот уникальный номер называется тегом и нужен для идентификации поля при сериализации и десериализации данных. Теги начинаются с 1 и могут достигать 536870911, кроме диапазона от 19000 до 19999, который зарезервирован для использования в будущем и не должен использоваться в пользовательских сообщениях. Эти теги позволяют protobuf эффективно кодировать данные, обеспечивая компактное представление сообщений и быстродействие при их обработке. При сериализации данных, т.е. переводе их в бинарный вид из нулей и единиц, сохраняются не имена полей, а их уникальные номера. Это делает процесс передачи данных более эффективным по сравнению с текстовыми форматами, такими как JSON или XML.

После первичного определения gRPC-сервиса в таблице можно составить proto-файл, в котором будут описаны не только входные/выходные сообщения для RPC-функций в формате protobuf, но и сами функции. Сервис определяется с помощью ключевого слова service, после которого идет его имя. В теле сервиса перечисляются функции, определенные с помощью ключевого слова rpc с указанием входных параметров и возвращаемых результатов для каждой функции.

Для моего примера этот proto-файл выглядит так:

syntax = "proto3";

import "google/protobuf/timestamp.proto"; //для работы с датой и временем

package order;

// ИНН поставщика
message ProviderINN {
  string inn = 1; // ИНН поставщика
}

// Информация о поставщике
message ProviderData {
  string inn = 1; // ИНН поставщика
  string name = 2; // Имя поставщика
  string phone = 3; // Телефон поставщика
  string email = 4; // Электронная почта поставщика
  string address = 5; // Адрес поставщика
}

// Информация о товаре в заказе
message OrderItem {
    string product = 1;
    int32 quantity = 2;
    double price = 3;
}

// Запрос на заказ
message OrderRequest {
  ProviderINN provider = 1; // Информация о поставщика
  repeated OrderItem item = 2; // Список товаров в заказе
}

// Унарный ответ на поток заказов
message OrderResponse {
    int32 quantity = 1;
    double amount = 2;
    google.protobuf.Timestamp orderdate = 3;
}

// Сервис
service OrderService {
  rpc GetInfoByINN (ProviderINN) returns (ProviderData);
  rpc StreamOrders (stream OrderRequest) returns (OrderResponse);
}

По своей сути, этот proto-файл является интерфейсом, который должны реализовать компоненты проектируемой системы, т.е. ее клиентская и серверная части. Заготовки для их фактической реализации на любом языке программирования генерируются автоматически из proto-файла с помощью protobuf-компилятора protoc. Сгенерированный код код включает в себя классы для сообщений, а также базовые классы и интерфейсы для реализации серверной логики и клиентских вызовов. Как это сделать, я расскажу в следующей статье, реализовав серверную и клиентскую часть рассмотренного gRPC-сервиса на Python.

Дизайн API — проектирование веб-приложений

Код курса
DAPI
Ближайшая дата курса
27 января, 2025
Продолжительность
16 ак.часов
Стоимость обучения
36 000 руб.

Больше примеров и подробностей про архитектуру и интеграцию информационных систем вы узнаете на моих курсах в Школе прикладного бизнес-анализа на базе нашего лицензированного учебного центра обучения и повышения квалификации системных и бизнес-аналитиков в Москве:

 

Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.