Микросервисы Microservices / Google / CSharp / Golang
Недавно вышел релиз gRPC. Сегодня я расскажу о том, что это такое и почему стоит, как минимум, обратить на это внимание. А потом расскажу, как посмотреть его в работе, используя стандартные примеры.
Чтобы не было скучно от слова “стандартные”, мы будем обращаться к серверу на Go из клиента на C#. В принципе, можно реализовать любые комбинации из языков программирования, которые поддерживаются 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 или перегруз сети).
Что касается универсальности, одним из объявленных принципов является применимость ко многим вариантам использования (и незначительным отличиям в производительности относительно заточенных под этот кейс решений). Сейчас про это рано говорить, однако, моя интуиция говорит о том, что у них получится.
Мотивация и принципы описаны в документации, я перечислю только некоторые из них (про универсальность уже сказал выше).
В gRPC используется protobuf как формат для обмена сообщениями (я уже отмечал выше, что концептуально можно использовать что-то другое). Protobuf используется как IDL, на основе которого генерируется клиентский и серверный код на выбранном ЯП.
К слову, в третьей версии (я так понял, они сделали её в основном для gRPC) protobuf получил несколько приятных плюшек:
Что мне понравилось в gRPC, помимо того, что он активно используется в инфраструктуре Google (даже в TensorFlow):
По поводу удачных вариантов использования (если отбросить рекламные лозунги), я вижу два основных:
Как водится, серебряных пуль не бывает и gRPC не исключение. Правда, правильнее было бы добавить к заголовку “пока нет”. Для gRPC уже достаточно много сторонних проектов и наверняка скоро станет ещё больше.
В gRPC поддерживаются четыре варианта вызовов.
В отличие от предыдущего случая, сервер возвращает “поток ответов”, и возвращает статус, когда все они отправлены.
В этом случае всё наоборот — клиент шлёт поток запросов, а сервер отсылает один ответ (обычно, но необязательно, после того как получены все клиентские запросы).
Всё как в предыдущих вариантах, только потоки у сервера и клиента независимы. И уже вам решать, как они будут взаимодействовать. Быть может, сервер будет ждать всех запросов, чтобы начать выдавать ответы, а сервер будет играть в “пинг-понг” с клиентом…
Поскольку я работаю в Windows, дальнейшее подразумевает эту операционку. Думаю, для других ОС разница будет невелика. Из набора примеров выбран Route Guide, как наиболее полно охватывающий все варианты вызовов.
Если вы ни разу не писали на Go (или у вас версия младше 1.5) — установите его, следуя инструкциям. Не забудьте установить переменную GOPATH — она нам понадобится.
Установите компилятор proto-файлов — protoc. Он обычно в конце списка файлов релиза с постфиксом “-win32.zip”. Затем скопируйте бинарник (protoc.exe) в папку, которая присутствует в PATH. Я подобные приложения и небольшие утилиты обычно складываю в папку “Programs”.
Итак, Go у вас установлен, теперь установите необходимые пакеты:
Важно: добавьте к PATH папку %GOPATH%\bin (в ней находится плагин protoc-gen-go.exe) и не забудьте перезапустить консоль. В принципе, и для Go и для C# исходный код уже сгенерирован, но вдруг вы захотите добавить что-то к proto-файлам.
После этого перейдите в папку c серверным кодом:
И поменяйте порт на 50052 (в примерах на разных языках временами используются разные порты, а нам нужно подружить C# и Go):
Теперь можно проверить, что proto-файлы компилируются и запустить сервер:
Если ваш firewall забьёт тревогу, успокойте его и переходите к следующему разделу.
Я использую классическую версию .NET и Visual Studio, для .NET Core всё будет немного отличаться.
Выберите папку, в которую вы хотите добавить папку “grpc” с примерами и запустите в ней:
Когда студия загрузится, скомпилируйте solution. Затем запустите RouteGuideClient — проще всего это сделать из студии. Но можно и из командной строки:
На случай, если вы захотите добавить что-то к proto-файлам, сгенерировать исходный код по ним можно с помощью командного файла generate_protos.bat.
Моё личное мнение — gRPC обязательно стоит попробовать, если вы делаете микросервисы и не сильно привязаны к альтернативам. Альтернативы, на мой взгляд – Apache Thrift и Cap’n Proto. Правда, слышал, что некоторые мигрируют с Apache Thrift на gRPC…
Если удастся плотно попробовать gRPC для реальной разработки — обязательно расскажу. Вы тоже делитесь :)
Микросервисы Microservices / Google / CSharp / Golang