В этом посте я собираюсь привести расширенный пример по теме, которая довольно популярна в наши дни: gRPC.

gRPC - это современный высокопроизводительный RPC-фреймворк с открытым исходным кодом, который может работать в любой среде. Он может эффективно соединять службы внутри и между центрами обработки данных с подключаемой поддержкой балансировки нагрузки, трассировки, проверки работоспособности и аутентификации. Это также применимо на последней миле распределенных вычислений для подключения устройств, мобильных приложений и браузеров к серверным службам. Grpc.io

gRPC также отлично подходит для использования в качестве протокола связи между микросервисами, написанными на разных языках программирования.

О gRPC можно сказать гораздо больше, однако я Я не буду вдаваться в подробности, так как предполагаю, что вы уже знакомы с ним. Если вы не знакомы с этим, вот отличная статья, в которой это подробно объясняется.

Когда я начал работать над gRPC, я быстро понял, что на самом деле он поставляется со встроенным механизмом сериализации и десериализации под названием Protobuf (буферы протокола). Буферы протокола - это не зависящий от языка и платформы, расширяемый механизм Google для сериализации структурированных данных - подумайте об XML, но меньше, быстрее и проще. Вы определяете, как вы хотите, чтобы ваши данные были структурированы один раз, а затем вы можете использовать специальный сгенерированный исходный код, чтобы легко записывать и считывать структурированные данные в различные потоки данных и из них, используя множество языков. Однако, если у вас нет определенного типа сообщения, вы почувствуете необходимость отключить сериализацию и десериализацию Protobuf. Давайте посмотрим, как это сделать в Go:

Следующий main.proto описывает службу Main, которая использует двунаправленную потоковую передачу Удаленный вызов процедур и передает необработанные данные. байты в качестве типа сообщения.

syntax = “proto3”;
package rpc;
service Main {
 rpc RPC (stream Payload) returns (stream Payload) {}
}
message Payload {
 bytes Data = 1;
}

После создания прото-файла нам нужно сгенерировать исходный код для сервера и клиента, используя этот файл:

 protoc -I main/ main.proto — go_out=plugins=grpc:main

Эта команда сгенерирует необходимый исходный код, который будет использоваться в вашем проекте. Следующим шагом является создание структуры Payload, которая будет передавать сообщение между парами сервер-клиент.

package rpc
// Payload defines the service message format.
type Payload struct {
 data []byte
}
// NewPayload creates and returns a new payload with the given byte slice.
func NewPayload(d []byte) *Payload {
 p := new(Payload)
 if d != nil {
 p.Set(d)
 }
 return p
}
// Set sets the payload
func (p *Payload) Set(d []byte) {
 p.data = d
}
// Get returns the payload
func (p *Payload) Get() []byte {
 return p.data
}

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

Подробнее