Первые впечатления о gRPC

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

Помните, я обещал поделиться впечатлениями о gRPC, когда доведётся попробовать в деле? Довелось. Сейчас поделюсь. Только уточню, что пока это впечатления с хакатона, там не будет махрового энтерпрайза, повального контроля с аудитом и тому подобного.

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

Техническая концепция

Концепция была простая — плагины к браузерам для упрощения заведения багов и набор сервисов (строго говоря — пока это консольные приложения). Цели — быстро сделать прототип, получив при этом удовольствие от исследования сравнительно новых для меня технологий. Исходя из целей, отметены были всякие консулы, grpc-gateway (для REST) — в основном, всё реализовывалось “в лоб”. В тот же лес ушла “безопасность”. Сервисы получились такие:

Что было использовано

Как видите, у меня был небольшой зоопарк из плагина к Chrome (сейчас в процессе плагин к IE), три приложения на Go и три на .NET. Всем им, естественно, хотелось между собой общаться (ладно, не всем, но я заставил почти всех :)

В такой ситуации gRPC показал себя крайне положительно, за исключением того, что в браузере он пока из коробки не работает. С другой стороны, написать на Go простенький HTTP API Server… Даже для такого ненастоящего гофера как я — дело 5 минут. По большому счёту, это потребовалось только для “session” (чтобы плагин мог получать и записывать необходимые данные) и для “bot” (Rocket.Chat пока тоже не умеет gRPC).

Что понравилось

Описание сервисов в proto-файлах. Действительно, описание “как бы контракта” в отдельном файле мотивирует думать над API, пока его пишешь (хотя protobuf v3 сравнительно толерантен к изменению API). Нравится, что есть в явном виде “сообщение”, а не набор параметров. Маленький пример:

service CentralService { // Registers specified Agent. rpc Register(Agent) returns (RegisterResponse) {}

Есть поддержка перечислений:

enum AgentType { ... // Redmine watching (singleton) Redmine = 4; ... }

Понравилось что относительно быстро генерируются прокси (что на Go, что на .NET). Прокси достаточно удобно использовать. Так выглядит сигнатура описанного выше метода на Go:

func (s *centralServer) Register(ctx context.Context, agent *a.Agent) (*a.RegisterResponse, error) { ...

А так вызов этого метода на .NET:

var channel = new Channel( Environment.GetEnvironmentVariable("MULTIDASH"), ChannelCredentials.Insecure); var central = new CentralService.CentralServiceClient(channel); ... central.Register(new Agent { Type = AgentType.Redmine, Host = Environment.MachineName, Port = port, ... });

И ещё (это субъективно, конечно) — эстетическое удовольствие от названия командного файла generate_protos.bat :) С ним, пожалуй, сравнится разве что использование хранилища “bolt” для “session”.

Что не понравилось

Не понравилось то, что падает в runtime, когда передаёшь null в поле сообщения. Столкнулся с этим, когда передавал строки на C# (в Go строки и так по умолчанию “” — там такой проблемы нет). Лечится, конечно, инциализацией в пустую строку. Но осадок остался.

Не столкнулся, но заочно не нравится скудный набор вариантов аутентификации из коробки (либо SSL/TLS, либо гугловый OAuth2). Понятно, что можно реализовать свой (возможно сейчас уже плодятся проекты на GitHub, которые это делают), но хотелось бы что-то тёплое, ламповое коробочное…

Резюме

В целом скорее понравилось, чем не понравилось. При случае, буду пробовать дальше.

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