Golang grpc.server: понятие сервера и сервисов

Я пытаюсь понять понятия Listener, Server и Services в контексте gRPC, Protobuf.

Давайте использовать пример на https://grpc.io/docs/languages/go/basics/ в качестве ссылки. Здесь у нас есть

  1. Слушатель: Лис
  2. Сервер gRPC: grpcServer: = grpc.NewServer ()
  3. Сервис: Сервис RouteGuide

Похоже, что на одном сервере может быть зарегистрировано несколько сервисов.

То есть, помимо услуги RouteGuide, мы можем сказать SomeOther Service, SomeOtherOther Service.

И мы можем зарегистрировать все три и ожидать, что сервер сможет обслуживать методы, принадлежащие этим трем службам (RouteGuide, SomeOther, SomeOtherOther).

Допустим, у каждого из RouteGuide, SomeOther, SomeOtherOther есть свои собственные прото-файлы, специфичные для них. И все прото находятся в одном пространстве имен (значение package).

grpcServer := grpc.NewServer(opts...)

newRouteGuideService := pb.NewRouteGuideServer()
pb.RegisterRouteGuideServer(grpcServer, newRouteGuideService)

someOtherService := pb.NewSomeOtherServer()
pb.RegisterSomeOtherServer(grpcServer, someOtherService)

someOtherOtherService := pb.NewSomeOtherOtherServer()
pb.RegisterSomeOtherOtherService(grpcServer, someOtherOtherService)

 lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", 80))
grpcServer.Serve(lis)

Похоже, термин «сервер» здесь, так сказать, перегружен. Не только grpcServer, но также RouteGuide, SomeOther и SomeOtherOther также называются серверами.

Я пытаюсь понять, как моделировать или понимать эти понятия.

Можно ли сказать, что сервер gRPCServer через прослушиватель lis прослушивает порт 80 и может обслуживать три службы RouteGuide, SomeOther, SomeOtherOther, которые зарегистрированы в нем (gRPCServer)? Подвержен ли один сервер, обслуживающий несколько сервисов, ошибкой? Какие предостережения следует иметь в виду при использовании одного сервера с несколькими службами?


person sam    schedule 16.12.2020    source источник


Ответы (3)


Помните, что Голанг композиционен. Итак, если вы изложите это в урезанной псевдо-манере:

// Simplified Example
//The interfaces would be made by your proto definition
type Service1 interface { 
   // does service 1 stuff
   ServiceHandler1()
   ServiceHandler2()
}

type S1 struct{}
func(*S1) ServiceHandler1() {
  //do svc1 stuff
}

type S2 struct{}
func(*S2) ServiceHandler2() {
  //do svc2 stuff
}

type S3 struct{
  // compose s1, s2
  S1
  S2
}

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

Итак, в приведенном выше случае я мог бы определить ServiceHandler1 и ServiceHander2 в proto rpc. Регистрация S1 не удовлетворила бы его, регистрация S2 - нет, но регистрация S3 - удовлетворит.

Точно так же вы можете разбить протокол rpc на две службы, одну для метода 1 и одну для метода 2, и обрабатывать их независимо. В этом случае вы можете зарегистрировать S1 для службы 1, S2 для службы 2 и S3 в качестве любого из них.

При поступлении запроса: Запрос - ›Слушатель -› Сервер GRPC - ›Мультиплексируется с обработчиком -› Создает горутину для обработки запроса

TL; DR; не имеет значения, откуда берутся вещи, если они удовлетворяют интерфейсу службы. Регистрации можно даже динамически изменять во время выполнения.

person Parcival    schedule 24.12.2020

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

Сеанс просто прослушивает запросы от подключенного клиента и отправляет их одной из зарегистрированных служб. Входящий запрос включает имя службы, вызываемую функцию и аргументы этой функции. Когда служба обрабатывает запрос, ответ отправляется обратно клиенту.

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

person Burak Serdar    schedule 20.12.2020
comment
Спасибо за ответ. Также имейте в виду предостережения, мне было интересно узнать о таких аспектах, как коллизии пространств имен. Например, должны ли эти различные услуги быть частью одного пакета? - person sam; 21.12.2020
comment
Упаковка не имеет значения с точки зрения работы, она просто создает пространство имен для символов. Если они слабо связаны или не связаны, храните их как отдельные пакеты. Если они тесно связаны, вы можете объединить их в один пакет. При выборе упаковки следует использовать шаблоны повторного использования и изоляции. - person Burak Serdar; 21.12.2020

Можно ли сказать, что сервер gRPCServer через прослушиватель прослушивает порт 80 и может обслуживать три сервиса RouteGuide, SomeOther, SomeOtherOther, которые зарегистрированы в нем (gRPCServer)?

да. Я не мог описать лучше.

Подвержен ли один сервер, обслуживающий несколько сервисов, ошибкой?

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

О чем следует помнить при использовании одного сервера с несколькими службами?

(мнение) Я ничего не имею в виду в данный момент, но, конечно, вам нужно с умом выбрать, какие службы будут обслуживаться вместе, потому что вы не хотите перегружать свой сервер или смешивать логику.

person rubens21    schedule 08.01.2021