- Оригинальный адрес:Почему мы переходим на gRPC
- Оригинальный автор:Levin Fritz
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:EmilyQiRabbit
- Корректор:wuyanan,suhanyujie
Если вы используете архитектуру микросервисов, вам необходимо принять одно из фундаментальных решений: как сервисы должны обмениваться информацией? Подход по умолчанию, по-видимому, заключается в использовании протокола HTTP для отправки сообщений JSON — так называемого REST API, но большинство людей не воспринимают принципы REST всерьез. FromAtoB с использованием REST API — это то, с чего мы начали, однако недавно мы решили сделать gRPC нашим новым стандартом.
gRPCЭто система удаленного вызова процедур, разработанная Google и имеющая открытый исходный код. Хотя он существует уже много лет, я не нашел в Интернете никакой информации о том, почему люди используют его или нет, поэтому я решил написать статью, объясняющую, почему мы выбрали gRPC.
Самым большим преимуществом gRPC является то, что он использует эффективное двоичное кодирование, что делает его намного быстрее, чем JSON/HTTP. Хотя более высокие скорости часто приветствуются, здесь есть еще два важных аспекта: четкая спецификация интерфейса и поддержка потоков.
Спецификация интерфейса gRPC
При создании новой службы gRPC первым шагом обычно является.proto
Интерфейс определяется в файле. Следующий код.proto
Общий формат файла - это упрощенная версия небольшой части нашего собственного API. В этом примере определен удаленный вызов процедуры «Поиск» вместе с ее входными и выходными типами.
syntax = "proto3";
package fromatob;
// FromAtoB 是 fromAtoB 后台 API 的简化版本。
service FromAtoB {
rpc Lookup(LookupRequest) returns (Coordinate) {}
}
// LookupRequest 是按照名称查找城市坐标的请求
message LookupRequest {
string name = 1;
}
// Coordinate 使用经度和纬度定义了地球上的坐标
message Coordinate {
// Latitude 是坐标的纬度,范围是 [-90, 90]。
double latitude = 1;
// Longitude 是坐标的经度,范围是 [-180, 180]。
double longitude = 2;
}
Используя этот файл, вы можете использоватьprotoc
Компилятор генерирует клиентский и серверный код, и вы можете начать писать код, который предоставляет или использует API.
Итак, почему этот файл дает нам преимущество, а не лишнюю работу? Давайте еще раз посмотрим на пример кода выше. Даже если вы никогда не использовали gRPC или Protocol Buffers, этот код очень удобочитаем: например, легко увидеть, что если вы хотите отправитьLookup
запрос, вы должны отправить строку типаname
параметр, этот запрос вернет вамCoordinate
результат типа, который содержит параметрыlatitude
иlongitude
. На самом деле, как только вы добавите несколько простых аннотаций, как в примере,.proto
Затем этот файл может служить документацией API для вашего сервиса.
Конечно, реальная спецификация сервиса должна быть намного больше, но не сложнее. просто будет больше для методаrpc
объявления и для типовmessage
утверждение.
пройти черезprotoc
Сгенерированный код также гарантирует, что данные, отправляемые клиентом или сервером, соответствуют спецификации. Это очень полезно для отладки. Дважды, как я помню, служба, которую я поддерживал, генерировала данные JSON в неправильном формате, и поскольку формат не был проверен, ошибка появлялась только в пользовательском интерфейсе. Единственный способ найти ошибки — это отладить интерфейсный код JavaScript, что непросто для бэкенд-разработчика, который никогда не использовал интерфейсный JavaScript-фреймворк!
Swagger / OpenAPI
В принципе, если вы используете как HTTP/JSON API, так иSwaggerили его преемникOpenAPI, вы также можете получить такое же преимущество. Следующий пример кода также сопоставим с gRPC API:
openapi: 3.0.0
info:
title: A simplified version of fromAtoB’s backend API
version: '1.0'
paths:
/lookup:
get:
description: Look up the coordinates for a city by name.
parameters:
- in: query
name: name
schema:
type: string
description: City name.
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Coordinate'
'404':
description: Not Found
content:
text/plain:
schema:
type: string
components:
schemas:
Coordinate:
type: object
description: A Coordinate identifies a location on Earth by latitude and longitude.
properties:
latitude:
type: number
description: Latitude is the degrees latitude of the location, in the range [-90, 90].
longitude:
type: number
description: Longitude is the degrees longitude of the location, in the range [-180, 180].
Сравните этот код со спецификацией gRPC. Появится код OpenAPIОченьТяжело читать! Он более подробный и сложный (восемь уровней отступов, в отличие от единственного в gRPC).
Аутентификация с помощью спецификации OpenAPI также намного сложнее, чем gRPC. По крайней мере, для внутренних сервисов все это означает, что спецификации либо не написаны, либо по мере итерации API становятся бесполезными, так как не обновляются.
поток
Ранее в этом году я начал разрабатывать новый API для нашей поисковой системы (представьте, что я ищу «пожалуйста, дайте мне все маршруты из Берлина в Париж на 1 июня 2019 года»). После того, как я создал первую версию API с использованием HTTP и JSON, мой коллега указал, что в некоторых случаях мне нужны результаты потокового запроса, а это означает, что, когда я получаю первый результат запроса, я должен снова начать отправлять эти результаты. Разработанный мной API просто возвращает простой массив JSON, поэтому служба не может отправлять запросы, пока не будут получены все результаты.
Использование такого API на внешнем интерфейсе требует, чтобы клиент инициировал запрос на опрос для получения результатов. Внешний интерфейс отправляет запросы POST для установки критериев поиска, а затем повторно отправляет запросы GET для получения результатов. Возвращаемые результаты будут содержать поле, подтверждающее завершение поиска. Это прекрасно работает, но не элегантно и требует, чтобы сервер использовал хранилище данных, такое как Redis, для кэширования промежуточных результатов. Новый API может быть реализован большим количеством более мелких сервисов, и я не хочу заставлять их всех реализовывать такую логику.
Итак, мы решили попробовать gRPC. Если вы хотите отправить результат удаленного вызова, используя gRPC, вам просто нужноstream
добавить ключевые слова в.proto
в файле. ЭтоSearch
Определение функции:
rpc Search (SearchRequest) returns (stream Trip) {}
protoc
Код, сгенерированный компилятором, содержитSend
Объект функций, которые наш сервисный код будет вызывать для отправки по однойTrip
объект, а также содержитRecv
Объект функции, которую клиентский код будет вызывать для получения результата. С точки зрения разработчика это проще, чем опрос приложений.полно.
Меры предосторожности
Также я хотел бы отметить, что gRPC также имеет некоторые недостатки. Все они касаются инструмента, а не самого протокола.
Когда вы создаете свой API с помощью HTTP/JSON, вы можете использовать curl, httpie или Postman для простого тестирования. Аналогичные инструменты есть и для gRPC, а именноgrpcurl, но с gRPC все не так гладко: нужно добавитьСопоставление службы gRPCрасширение или указать в каждой команде соответствующий.proto
документ. Мы подумали, что будет проще добавить небольшой инструмент командной строки на стороне сервера, который может отправлять простые запросы. иprotoc
Сгенерированный клиентский код уже делает отправку запросов очень простой.
Еще одна большая проблема — балансировка нагрузки Kubernetes. Балансировка нагрузки, которую мы использовали для HTTP-сервисов, не очень подходит для gRPC. По сути, балансировка нагрузки, необходимая для gRPC, осуществляется на уровне приложения, а не на уровне соединения TCP. Чтобы решить эту проблему, мы обращаемся к учебнику:gRPC Load Balancing on Kubernetes without Tears,созданныйLinkerd.
Суммировать
Хотя для создания gRPC API потребуется дополнительная предварительная работа, мы обнаружили, что преимущества наличия четкой спецификации API и поддержки потоковой передачи более чем компенсируют предварительную работу. Для нас gRPC будет выбором по умолчанию для всех новых внутренних сервисов, которые мы будем создавать.
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллекти другие поля, если вы хотите видеть больше качественных переводов, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.