gRPC

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

gRPC
Тип Remote procedure call framework
Разработчик Google
Написана на Android Java, C#, C++, Dart, Go, Java, Kotlin/JVM, Node.js, Objective-C, PHP, Python, Ruby
Первый выпуск август 2016; 5 лет назад (2016-08)
Последняя версия 1.33.2
Лицензия Apache License 2.0
Сайт grpc.io

gRPC (Remote Procedure Calls) — это система удалённого вызова процедур (RPC) с открытым исходным кодом, первоначально разработанная в Google в 2015 году. В качестве транспорта используется HTTP/2, в качестве языка описания интерфейса — Protocol Buffers. gRPC предоставляет такие функции как аутентификация, двунаправленная потоковая передача и управление потоком, блокирующие или неблокирующие привязки, а также отмена и тайм-ауты. Генерирует кроссплатформенные привязки клиента и сервера для многих языков. Чаще всего используется для подключения служб в микросервисном стиле архитектуры и подключения мобильных устройств и браузерных клиентов к серверным службам.

Сложное использование HTTP/2 в gRPC делает невозможным реализацию клиента gRPC в браузере - вместо этого требуется прокси.

Аутентификация[править | править код]

gRPC поддерживает использование TLS и аутентификации на основе токенов. Подключение к сервисам Google должно использовать TLS. Существует два типа учетных данных: учетные данные канала и учетные данные для вызова.

Способ кодирования данных[править | править код]

gRPC использует Protocol Buffers для кодирования данных. В отличие от HTTP API с JSON, они имеют более строгую спецификацию.

Обзор[править | править код]

В gRPC клиентское приложение может напрямую вызывать метод серверного приложения на другом компьютере, как если бы это был локальный объект, что упрощает создание распределенных приложений и служб. Как и во многих системах RPC, gRPC основан на идее определения службы, определяя методы, которые могут быть вызваны удаленно с их параметрами и типами возвращаемых данных. На стороне сервера сервер реализует этот интерфейс и запускает сервер gRPC для обработки клиентских вызовов. На стороне клиента есть заглушка (называемая на некоторых языках просто клиентом), которая предоставляет те же методы, что и сервер.

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

gRPC client-server communication

Основные концепции, архитектура и жизненный цикл[править | править код]

Как и многие системы RPC, gRPC основан на идее определения службы, определяя методы, которые могут быть вызваны удаленно (с нужными параметрами и типами возвращаемых данных). По умолчанию gRPC использует Protobuf как язык определения интерфейса (IDL) для описания интерфейса службы и структуры сообщений полезной нагрузки. При желании можно использовать другие альтернативы.

gRPC позволяет определить четыре типа методов обслуживания:

  • Унарный RPC (Unary RPC) — клиент отправляет один запрос на сервер и получает один ответ обратно, как при обычном вызове функции.
  • Серверные потоковые RPC (Server streaming RPC), когда клиент отправляет запрос на сервер и получает поток для чтения последовательности сообщений обратно. Клиент читает из возвращенного потока, пока не кончатся сообщения. gRPC гарантирует упорядочение сообщений в рамках отдельного вызова RPC.
  • Клиентские потоковые RPC (Client streaming RPC), в которых клиент записывает последовательность сообщений и отправляет их на сервер, снова используя предоставленный поток. После того, как клиент закончил писать сообщения, он ждет, пока сервер прочитает их и вернет свой ответ. Опять же, gRPC гарантирует упорядочение сообщений в рамках отдельного вызова RPC.
  • RPC с двунаправленной потоковой передачей (Bidirectional streaming RPC), где обе стороны отправляют последовательность сообщений, используя поток чтения-записи. Два потока работают независимо, поэтому клиенты и серверы могут читать и писать в любом порядке: например, сервер может дождаться получения всех клиентских сообщений, прежде чем записывать свои ответы, или он может поочередно читать сообщение, а затем писать сообщение, или какая-то другая комбинация чтения и записи. Порядок сообщений в каждом потоке сохраняется.

Использование API[править | править код]

Начиная с определения службы в .protoфайле, gRPC предоставляет плагины компилятора Protocol Buffers, которые генерируют клиентский и серверный код. Пользователи gRPC обычно вызывают эти API на стороне клиента и реализуют соответствующий API на стороне сервера.

  • На стороне сервера сервер реализует методы, объявленные службой, и запускает сервер gRPC для обработки клиентских вызовов. Инфраструктура gRPC декодирует входящие запросы, выполняет методы обслуживания и кодирует ответы служб.
  • На стороне клиента у клиента есть локальный объект, известный как stub (заглушка) (для некоторых языков предпочтительным термином является клиент), который реализует те же методы, что и служба. Затем клиент может просто вызвать эти методы для локального объекта, заключив параметры вызова в соответствующий тип сообщения протокола Protocol Buffers. gRPC следит за отправкой запроса (-ов) на сервер и возвращением ответа (-ов) ProtocolBuffers-сервера.

Синхронность и асинхронность[править | править код]

Синхронные вызовы RPC, которые блокируются до тех пор, пока от сервера не поступит ответ, являются наиболее близким приближением к абстракции вызова процедуры, к которому стремится RPC. С другой стороны, сети по своей сути асинхронны, и во многих сценариях полезно иметь возможность запускать RPC, не блокируя текущий поток.

API программирования gRPC на большинстве языков имеет как синхронную, так и асинхронную разновидности.

Жизненный цикл RPC[править | править код]

Унарный RPC[править | править код]

Клиент отправляет один запрос и возвращает один ответ.

  1. После того, как клиент вызывает метод-заглушку, сервер уведомляется о том, что RPC был вызван с метаданными клиента для этого вызова, именем метода и указанным крайним сроком, если это применимо.
  2. Затем сервер может либо сразу отправить обратно свои собственные исходные метаданные (которые должны быть отправлены перед любым ответом), либо дождаться сообщения запроса от клиента. Что происходит первым, зависит от конкретного приложения.
  3. Когда сервер получает сообщение запроса клиента, он выполняет всю работу, необходимую для создания и заполнения ответа. Затем ответ возвращается (в случае успеха) клиенту вместе со сведениями о состоянии (код состояния и необязательное сообщение о состоянии) и необязательными конечными метаданными.
  4. Если статус ответа «ОК», то клиент получает ответ, который завершает вызов на стороне клиента.

Серверный потоковый RPC[править | править код]

RPC с потоковой передачей на сервере похож на унарный RPC, за исключением того, что сервер возвращает поток сообщений в ответ на запрос клиента. После отправки всех сообщений клиенту отправляются сведения о состоянии сервера (код состояния и необязательное сообщение о состоянии) и дополнительные конечные метаданные. На этом обработка на стороне сервера завершена. Клиент завершает работу, когда получает все сообщения сервера.

Клиент потоковой передачи RPC[править | править код]

Клиентский RPC с потоковой передачей похож на унарный RPC, за исключением того, что клиент отправляет на сервер поток сообщений вместо одного сообщения. Сервер отвечает одним сообщением (вместе со сведениями о его статусе и дополнительными конечными метаданными), как правило, но не обязательно после того, как он получил все сообщения клиента.

Двунаправленный потоковый RPC[править | править код]

В RPC с двунаправленной потоковой передачей вызов инициируется клиентом, вызывающим метод, и сервером, получающим метаданные клиента, имя метода и крайний срок. Сервер может выбрать отправку своих исходных метаданных или дождаться, пока клиент начнет потоковую передачу сообщений.

Обработка потока на стороне клиента и на стороне сервера зависит от приложения. Поскольку два потока независимы, клиент и сервер могут читать и писать сообщения в любом порядке. Например, сервер может дождаться, пока он получит все сообщения клиента, прежде чем писать свои сообщения, или сервер и клиент могут играть в «пинг-понг» — сервер получает запрос, затем отправляет ответ, затем клиент отправляет другой запрос, основанный на ответе, и так далее.

Дедлайны / Тайм-ауты[править | править код]

gRPC позволяет клиентам указать, как долго они готовы ждать завершения RPC, прежде чем RPC завершится с ошибкой. На стороне сервера сервер может запросить, не истек ли тайм-аут определенного RPC или сколько времени осталось для завершения RPC.

Указание крайнего срока или тайм-аута зависит от языка: некоторые языковые API работают в терминах тайм-аутов (продолжительности времени), а некоторые языковые API работают в терминах крайнего срока (фиксированный момент времени) и могут иметь или не иметь крайний срок по умолчанию.

Прекращение RPC[править | править код]

В gRPC и клиент, и сервер делают независимые и локальные определения успешности вызова, и их выводы могут не совпадать. Это означает, что, например, у вас может быть RPC, который успешно завершается на стороне сервера, но терпит неудачу на стороне клиента. Сервер также может принять решение о завершении до того, как клиент отправит все свои запросы.

Отмена RPC[править | править код]

Клиент или сервер могут отменить RPC в любое время. Отмена немедленно завершает RPC, поэтому дальнейшая работа не выполняется.

Метаданные[править | править код]

Метаданные — это информация о конкретном вызове RPC (например, сведения об аутентификации) в форме списка пар ключ-значение, где ключи являются строками, а значения обычно являются строками, но могут быть двоичными данными. Метаданные непрозрачны для самого gRPC — они позволяют клиенту предоставлять информацию, связанную с вызовом на сервер, и наоборот.

Доступ к метаданным зависит от языка.

Каналы[править | править код]

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

Как gRPC решает закрыть канал, зависит от языка. Некоторые языки также позволяют запрашивать состояние канала.

Принятие[править | править код]

Ряд различных организаций приняли gRPC, такие как Square, Netflix, IBM, CoreOS, Docker, CockroachDB, Cisco, Juniper Networks,[1] Spotify,[2] и Dropbox.[3]

В проекте с открытым исходным кодом u-bmc вместо IPMI используется gRPC. 8 января 2019 года Dropbox объявил, что следующая версия Courier, их RPC-фреймворк, лежащий в основе их архитектуры SOA, будет переведен на gRPC, прежде всего потому, что он хорошо согласован с их существующими пользовательскими RPC-фреймворками.

См. также[править | править код]

Примечания[править | править код]

  1. gRPC. grpc.io. Дата обращения: 24 февраля 2020. Архивировано 24 ноября 2020 года.
  2. gRPC at Spotify. jfokus.se. Дата обращения: 12 мая 2020. Архивировано 27 октября 2021 года.
  3. How we migrated Dropbox from Nginx to Envoy. Dropbox.Tech. Дата обращения: 30 октября 2020. Архивировано 4 января 2022 года.

Ссылки[править | править код]