Проблема
Когда мы разрабатываем приложение, которое разделено на независимые автономные компоненты, мы говорим о микросервисной архитектуре. Для взаимодействия компонентов используется API. Самый популярным API является REST. Это обусловлено его гибкостью, эффективностью (в большинстве сценариев) и тем, что он легко масштабируется.
Большая часть реализаций REST использует стандарт JSON для обмена сообщениями. Обычно это удобно — сама по себе такая структура легко читается людьми и предоставляет независимость от языка программирования.
Недостатками такого решения является избыточность данных и сущностей из которых состоит запрос. В большинстве случаев это некритично. Проблемы начинаются в сценариях, когда нужно передавать много данных с низкой задержкой.
Зачем нужен gRPC
gRPC (Remote Procedure Calls) — это система удалённого вызова процедур (RPC) с открытым исходным кодом, первоначально разработанная в Google. В качестве основного протокола передачи применяется HTTP/2, для описания процедур применяется “Protocol Buffers”. Это в свою очередь приносит дополнительные преимущества: сжатие HTTP-заголовков и мультиплексирование запросов.
gRPC предполагает возможность аутентификации, потоковой передачи данных в любую сторону, управление потоками, отмену и time-out запросов, при этом выделяется кроссплатформенностью за счет генерации исходного кода классов для всех популярных языков программирования.

Когда использовать gRPC
Статистика говорит о том, что gRPC используется гораздо реже, чем REST. К сожалению, часто только из-за этого разработчики выбирают REST. И если в небольших проектах это оправдано, тогда напрашивается вопрос: в каких случаях правильным выбором всё же будет gRPC?
Стоит взглянуть на таблицу их основных отличий.
|
Сравнение gRPC и REST |
||
|
Технология |
gRPC |
REST |
|
Протокол |
http 2.0 |
http 1.1 |
|
Формат обмена данными |
protobuf |
JSON |
|
Избыточность |
Нет |
Да |
|
Декларативность |
Единый .proto файл |
Нет единого соглашения |
Хотя REST подход также может использовать HTTP 2 для обмена данными, тем не менее он будет ограничен моделью запрос-ответ, при которой не применяется поддержка двусторонней потоковой передачи данных возможной для HTTP При этом, конечно же сохраняется возможность унарных взаимодействий, которые реализует HTTP 1.1 (один запрос — один ответ).
В конечном итоге мы получаем более высокую скорость ответа в разных сценариях.

При этом в gRPC наименования полей, ожидаемых запросов и возвращаемых ответов определяется и описывается в одном месте — в файле .proto. И если вы хотя бы раз разрешали конфликты в наименовании полей вида ObjectID и object_id, то вам определенно понравится работать с gRPC.
Пример .proto файла:
syntax = "proto3"; /* Наименование пакета данных */ message Calculator { int32 xxx = 1; int32 yyy = 2; } message CalculatorRequest { Calculator calculator = 1; } message CalculatorResponse { int32 result = 1; }
Когда не использовать gRPC
gRPC при всех своих достоинствах не лишен недостатков. Вот парочка:
-
Использование HTTP/2 в gRPC, что делает невозможным реализацию клиента gRPC в браузере — вместо этого приходится использовать прокси.
-
Более сложная отладка по сравнению с REST из-за бинарного обмена сообщениями
Реальный кейс
Как упоминалось выше, для работы с gRPC достаточно одного .proto файла.
Мы делали реализацию API на Python, где использовали дуплексное (двунаправленное соединение) для сервиса потокового распознавания речи в текст.
Дуплексное соединение gRPC на Python:
def stream_recorder(self) -> Union[RecognitionRequest, str]: """Потоковый захват речи""" for _ in range(0, int(self.rate / self.chunk * self.seconds)): data = self.stream.read(self.chunk, exception_on_overflow=False) yield RecognitionRequest(audio=data) def stream_recognize(self) -> str: """Потоковое распознавание речи""" credentials = grpc.ssl_channel_credentials() with grpc.secure_channel(f'{settings.SPEECH_SERVER}:{settings.SPEECH_PORT}', credentials=credentials) as chennel: stub = VoiceAssistantServiceStub(chennel) metadata = [('authorization', f'Bearer {settings.SPEECH_API_TOKEN}'), ('audioformat', 'lpcm')] for response in stub.RecognizeAudio(self.stream_recorder(), metadata=metadata): if response.chunks[0].final: return response.chunks[0].text.strip()
Эти декларативные преимущества gRPC работают не только в момент написания кода. Особенно удобно делать отладку соединения в Postman, который предоставляет поддержку протокола.
Даже не имея доступа к удаленному серверу мы можем имитировать запросы с моковыми данными и эмулировать ответ нажатием одной кнопки.

Выводы
В отличие от REST, gRPC — решение, которое не зависит от платформы и языка. И благодаря HTTP/2 и протоколу Protobuf решает проблемы, связанные со скоростью передачи данных, их весом, в результате повышая эффективность обмена сообщениями.
ссылка на оригинал статьи https://habr.com/ru/post/706114/
Добавить комментарий