Каково точное использование исполнителя в ServerBuilder grpc-java? Он просто выполняет методы обработчика?

grpc-java использует исполнитель в своем ServerBuilder, который, если он не определен методом builder.executor(), по умолчанию использует статический кэшированный пул потоков. Каково точное использование этого исполнителя? Он просто выполняет методы обработчика или также делает «что-то еще»?

Кроме того, как grpc определяет netty worker EventLoopGroup? В частности, я хочу знать, как рабочие потоки назначаются этой рабочей группе. Существует ли количество потоков по умолчанию или это функция количества ядер машины? Кроме того, в связи с вышеуказанным вопросом, как эти рабочие сети работают с исполнителем? Обрабатывают ли они только ввод-вывод — чтение и запись в канал?

Редактировать: Netty по умолчанию создает (2 * количество ядер) рабочие потоки.


person gravetii    schedule 23.02.2017    source источник


Ответы (1)


Предоставляемый вами Executor — это то, что фактически выполняет обратные вызовы rpc. Это освобождает EventLoop для продолжения обработки данных в соединении. Когда из сети приходит новое сообщение, оно считывается в цикле событий, а затем распространяется вверх по стеку к исполнителю. Исполнитель принимает сообщения и передает их вашему ServerCall.Listener, который фактически выполняет обработку данных.

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

Чтобы настроить группу циклов событий, вы вызываете workerEventLoopGroup в NettyServerBuilder. gRPC не зависит строго от Netty (возможны другие серверные транспорты), поэтому необходимо использовать специальный построитель Netty.

person Carl Mastrangelo    schedule 23.02.2017
comment
есть ли у gRPC рекомендуемый исполнитель для различных сценариев, поскольку настоятельно рекомендуется не использовать значение по умолчанию? - person Matt; 23.08.2017
comment
Да, используйте пул потоков фиксированного размера. Что-то вроде Executors.newFixedThreadPool(16) - person Carl Mastrangelo; 23.08.2017
comment
спасибо, Карл, так что это означает, что мой *ServiceImplBase должен быть потокобезопасным, если я добавлю один экземпляр .addService(...) на свой сервер и у меня будет несколько потоков, отправляющих запросы? - person Matt; 25.08.2017
comment
@user3833308 user3833308 можно использовать инфраструктуру внедрения зависимостей для простого доступа к управляемому каналу из каждой реализации службы. - person Joseph Orlando; 01.06.2019
comment
Вы передаете threadlocals с помощью ServerInterceptor и присоединяете/отсоединяете io.grpc.Context. Прочитайте из threadlocal при подключении и удалите его при отсоединении. - person Carl Mastrangelo; 04.06.2019