Рубріки: Теория

Что такое gRPC и как он работает

Сергій Бондаренко

Пришло время разобраться, что такое gRPC — в чем принцип его работы и какие у него преимущества перед привычным REST API.

Разработанный в 2016 году компанией Google, фреймворк gRPC быстро стал популярным и сегодня активно используется как в самом Google, так и в ряде крупных проектов, среди которых, например, Netflix, Cisco, Dropbox, Spotify и др. Система вызова удаленных процедур gRPC является альтернативой привычному REST API и наиболее полезна в контексте микросервисов. Ее часто можно встретить там, где приходится обслуживать большое количество клиентов. Все чаще крупные проекты переходят на микросервисную архитектуру, все большее число компаний принимают gRPC в качестве стандарта передачи данных вместо REST API. Как он работает и в чем его преимущество?

Принцип работы gRPC

Идея gRPC не нова – парадигма, которую использует данный фреймворк, уже давно известна, она основывается на RPC (удаленный вызов процедур). При задействовании RPC происходит коммуникация между клиентом и сервером, для которой используется не HTTP-вызов, а вызов функции. Клиент вызывает удаленную процедуру, сериализует параметры и дополнительную информацию в сообщении, после чего шлет сообщение на сервер. Приняв данные, сервер производит их десериализацию, выполняет запрошенную операцию и шлет результат обратно клиенту. Такие объекты как stub сервера и stub клиента берут на себя функцию сериализации и десериализации  параметров. 

Рассмотрим следующий пример – у нас есть большое монолитное приложение, которое имеет единый общий модуль и которое работает на одном сервере. Постепенно это приложение развивается, добавляются новые возможности, появляются новые опции. По мере разрастания монолитного приложения, вносить в него изменения становится все труднее, масштабирование проекта затрудняется. Дополнительные возможности приложения, его новые функции заметно увеличивают нагрузку на сервер, а потому требуют все больше аппаратных мощностей. До определенного момента этих мощностей будет хватать. Но, рано или поздно, придется столкнуться с проблемой ограниченности ресурсов сервера. Мощности компьютера нельзя увеличивать до бесконечности и в какой-то момент достигается потолок, ограничивающий вертикальное масштабирование проекта. 

В качестве решения этой проблемы используют деление монолитного приложения на отдельные, небольшие, слабо связанные маленькие приложения — микросервисы.  Каждый такой микросервис – это автономное приложение. Микросервисы общаются друг с другом и, взаимодействуют, выполняя функции итогового приложения. Если в монолитной архитектуре пользователь обращается к приложению и получает ответ, то, в случае с микросервисной архитектурой он обращается к микросервису. Этот микросервис, в свою очередь, обращается к другому микросервису, тот, например, может обратиться к третьему микросервису или к базе данных и т.д. Общаясь между собой с помощью программного интерфейса API, совокупность микросервисов формирует все приложение целиком. 

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

Кроме того, когда мы вносим изменения в монолитное приложение, по причине обилия связей между разными его частями, это может повлечь за собой изменение тех или иных модулей. В микросервисной же архитектуре приложение декомпозировано на множество приложений — поэтому вносить изменения только в какой-то определенный модуль относительно легко и безопасно.

Однако у микросервисной архитектуры есть и минусы. Чем больше микросервисов используется в проекте, тем большее количество программных интерфейсов API необходимо создавать, обеспечивая взаимодействие микросервисов.

Стандартный способ реализации API и организации общения с приложениями — посредством REST API. Вкратце это выглядит так: имеется клиент и сервер, который имеет доступ к базе данных. Клиент посылает какой-то HTTP-запрос с определенным методом, передавая (или не передавая) данные JSON. Сервер принимает этот HTTP-запрос и отправляет ответ (обычно, тоже в формате JSON или, реже – в виде XML). Один из недостатков REST API заключается в том, что для отдельно взятого языка программирования нужно создавать свой код API. Все языки программирования имеют собственные библиотеки для разработки API, и каждый раз код приходится писать вручную. Конечно, можно генерировать код с помощью сторонних инструментов (например, Swagger), но стандартного способа выполнить это в REST API — увы нет.

Другое неудобство REST API состоит в том, что формат данных, используемый для пересылки данных – не бинарный, а текстовый. Такой формат удобен для визуального ознакомления с содержимым, однако, он никак не оптимизируется, не сжимается при передаче. Соответственно размер передаваемого сообщения получается большой и время на его отсылку увеличивается. Если бы данные были бинарными, мы бы могли применить к ним сжатие. 

Ну, и третий недостаток REST API состоит в том, что транспортный протокол, применяемый для передачи данных – HTTP 1.1. Поэтому организация стриминга потоковых данных затруднена.

Преимущества gRPC

Перечисленные выше недостатки были устранены в gRPC, благодаря чему фреймворк стремительно обрел популярность. Система обмена сообщениями gRPC использует вместо JSON бинарный формат Protobuf, благодаря чему размер сообщений становится меньше и увеличивается пропускная способность —  скорость передачи в конечном итоге возрастает в 7-10 раз. Этот формат поддерживает строгую типизацию, однако, для его чтения необходимо декодировать сообщение, а для отправки – кодировать.

Буфер протокола Protobuf позволяет хранить свои данные и функциональные контракты в виде proto файла. Клиент и сервер обязаны хранить один и тот же proto файл, он действует как посреднический контракт для клиента для вызова любых доступных функций с сервера. Для proto файлов применяют язык описания интерфейсов (IDL). В proto файле мы описываем типы данных, формат сообщений и те RPC операции, которые предполагается использовать в приложении. Скажем, для описания структуры данных сообщения, нужно добавить message, имя структуры, внутри тип, имя и номер поля. В отличие от Protobuf, JSON не обладает строгой типизацией – ключу “timestamp” может соответствовать и строка, и число. В Protobuf же можно указать, что какая-то колонка (“timestamp”) – это целое число. При пересылке массива объектов JSON наблюдается избыточность — многократно передаются одни и те же ключи (“timestamp” и “url”), в Protobuf избыточности нет. 

В gRPC присутствуют стандартные средства для генерации кода на разных языках программирования – компилятор protoc переводит язык, который мы используем в proto файле, в любой из популярных языков программирования, включая Python, Java, C++, Golang и т.д. 

Бинарный формат, используемый в gRPC транслируется через протокол HTTP 2, благодаря чему скорость обмена данными (согласно отдельным тестам) увеличивается на 14 процентов. В HTTP 2 хорошо реализованы потоки данных (можно делать запрос к серверу и получать от него поток данных по каналу клиент-сервер).

Типы RPC

Благодаря мультиплексированию на HTTP 2, реализация стриминга потоковых данных не является проблемой. Различают следующие виды RPC:

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

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

Когда целесообразно использовать gRPC

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

Если приложение использует архитектуру микросервисов, в котором многочисленные микросервисы общаются друг с другом, то выбор следует делать в сторону gRPC. В этом случае у вас могут использоваться разные языки программирования (что, впрочем, не проблема и для REST API, если использовать Swagger), а также большое количество передач сообщений. Соответственно на gRPC вы можете использовать автоматическую генерацию кода и получите более высокую скорость работы в сравнении с REST API. Также gRPC актуален в случаях, когда необходим стриминг данных.

Перехватчики (Interceptors) и балансировка нагрузки

В арсенале gRPC присутствует механизм расширения, который называется перехватчик (interceptor). Когда необходимо изменить запрос или ответ перед передачей, можно перехватить вызов и изменить его (аналог промежуточного ПО в REST API). Interceptors удобно использовать для логирования запросов, сбора метрик, аутентификации и др.

Также gRPC поддерживает механизм балансировки нагрузки клиента – он уже реализован с помощью библиотеки Golang.

Заключение

Теперь вы имеете представление о том, что такое gRPC,  какие у него преимущества и особенности работы, в каких случаях данный фреймворк применяется. Для более детального погружения в тему рекомендуем вам посмотреть вебинар, на котором будет рассмотрены технологии gRPC и REST на основе реального проекта.

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023