gRPC — первые шаги

Микросервисы Microservices  /  Google  /  CSharp  /  Golang

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

Чтобы не было скучно от слова “стандартные”, мы будем обращаться к серверу на Go из клиента на C#. В принципе, можно реализовать любые комбинации из языков программирования, которые поддерживаются gRPC. Кстати, вот список поддерживаемых платформ и ЯП:

Что такое gRPC

Цитата: A high performance, open-source universal RPC framework.

Что такое Remote Procedure Call объяснять не буду, давайте разберёмся с высокой производительностью и универсальностью. Но сначала немного истории.

Жил да был в Stubby — инфраструктура Google для связи между большим количеством микросервисов. Шли годы, то что было специфично для Google становилось общедоступными стандартами (вроде HTTP/2). Поэтому в Google решили переработать Stubby и открыть код. Как вы уже догадались, gRPC использует HTTP/2, что позволяет выполнять много мелких запросов быстро (без открытия нового TCP-соединения).

Для справки, в проекте etcd переход на gRPC дал прирост производительности приблизительно в 42 раза :) Правда, они честно признаются, что сравнимых результатов можно добиться и при использовании большого количества TCP-соединений на HTTP/1.x (если при этом не упрёшься в количество дескрипторов Linux или перегруз сети).

Что касается универсальности, одним из объявленных принципов является применимость ко многим вариантам использования (и незначительным отличиям в производительности относительно заточенных под этот кейс решений). Сейчас про это рано говорить, однако, моя интуиция говорит о том, что у них получится.

Принципы и концепция

Мотивация и принципы описаны в документации, я перечислю только некоторые из них (про универсальность уже сказал выше).

Protobuf v3

В gRPC используется protobuf как формат для обмена сообщениями (я уже отмечал выше, что концептуально можно использовать что-то другое). Protobuf используется как IDL, на основе которого генерируется клиентский и серверный код на выбранном ЯП.

К слову, в третьей версии (я так понял, они сделали её в основном для gRPC) protobuf получил несколько приятных плюшек:

Что мне понравилось в gRPC и где он может быть эффективно использован

Что мне понравилось в gRPC, помимо того, что он активно используется в инфраструктуре Google (даже в TensorFlow):

По поводу удачных вариантов использования (если отбросить рекламные лозунги), я вижу два основных:

Чего нет в gRPC

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

Варианты вызовов

В gRPC поддерживаются четыре варианта вызовов.

Unary RPC

Server streaming RPC

В отличие от предыдущего случая, сервер возвращает “поток ответов”, и возвращает статус, когда все они отправлены.

Client streaming RPC

В этом случае всё наоборот — клиент шлёт поток запросов, а сервер отсылает один ответ (обычно, но необязательно, после того как получены все клиентские запросы).

Bidirectional streaming RPC

Всё как в предыдущих вариантах, только потоки у сервера и клиента независимы. И уже вам решать, как они будут взаимодействовать. Быть может, сервер будет ждать всех запросов, чтобы начать выдавать ответы, а сервер будет играть в “пинг-понг” с клиентом…

Настройка окружения

Поскольку я работаю в Windows, дальнейшее подразумевает эту операционку. Думаю, для других ОС разница будет невелика. Из набора примеров выбран Route Guide, как наиболее полно охватывающий все варианты вызовов.

Go

Если вы ни разу не писали на Go (или у вас версия младше 1.5) — установите его, следуя инструкциям. Не забудьте установить переменную GOPATH — она нам понадобится.

Установите компилятор proto-файлов — protoc. Он обычно в конце списка файлов релиза с постфиксом “-win32.zip”. Затем скопируйте бинарник (protoc.exe) в папку, которая присутствует в PATH. Я подобные приложения и небольшие утилиты обычно складываю в папку “Programs”.

Итак, Go у вас установлен, теперь установите необходимые пакеты:

go get google.golang.org/grpc go get -u github.com/golang/protobuf/proto go get -u github.com/golang/protobuf/protoc-gen-go

Важно: добавьте к PATH папку %GOPATH%\bin (в ней находится плагин protoc-gen-go.exe) и не забудьте перезапустить консоль. В принципе, и для Go и для C# исходный код уже сгенерирован, но вдруг вы захотите добавить что-то к proto-файлам.

После этого перейдите в папку c серверным кодом:

cd %GOPATH%\src\google.golang.org\grpc\examples\route_guide\server

И поменяйте порт на 50052 (в примерах на разных языках временами используются разные порты, а нам нужно подружить C# и Go):

var ( ... port = flag.Int("port", 50052, "The server port") )

Теперь можно проверить, что proto-файлы компилируются и запустить сервер:

cd %GOPATH%\src\google.golang.org\grpc\examples\route_guide protoc -I routeguide/ routeguide/route_guide.proto --go_out=plugins=grpc:routeguide go run server/server.go

Если ваш firewall забьёт тревогу, успокойте его и переходите к следующему разделу.

C#

Я использую классическую версию .NET и Visual Studio, для .NET Core всё будет немного отличаться.

Выберите папку, в которую вы хотите добавить папку “grpc” с примерами и запустите в ней:

git clone -b v1.0.x https://github.com/grpc/grpc cd grpc\examples\csharp\route_guide RouteGuide.sln

Когда студия загрузится, скомпилируйте solution. Затем запустите RouteGuideClient — проще всего это сделать из студии. Но можно и из командной строки:

cd RouteGuideClient/bin/Debug RouteGuideClient.exe

На случай, если вы захотите добавить что-то к proto-файлам, сгенерировать исходный код по ним можно с помощью командного файла generate_protos.bat.

Резюме

Моё личное мнение — gRPC обязательно стоит попробовать, если вы делаете микросервисы и не сильно привязаны к альтернативам. Альтернативы, на мой взгляд – Apache Thrift и Cap’n Proto. Правда, слышал, что некоторые мигрируют с Apache Thrift на gRPC…

Если удастся плотно попробовать gRPC для реальной разработки — обязательно расскажу. Вы тоже делитесь :)

Микросервисы Microservices  /  Google  /  CSharp  /  Golang