grpc-java的ServerBuilder中executor的具体用途是啥?它只是执行处理程序方法吗?

Posted

技术标签:

【中文标题】grpc-java的ServerBuilder中executor的具体用途是啥?它只是执行处理程序方法吗?【英文标题】:What is the exact use of the executor in grpc-java’s ServerBuilder? Does it just execute the handler methods?grpc-java的ServerBuilder中executor的具体用途是什么?它只是执行处理程序方法吗? 【发布时间】:2017-07-13 12:20:41 【问题描述】:

grpc-java 在其ServerBuilder 中使用了一个执行器,如果builder.executor() 方法没有定义它,则默认使用静态缓存线程池。这个执行器的具体用途是什么?它只是执行处理程序方法还是也做“其他事情”?

另外,grpc是如何定义netty workerEventLoopGroup的?具体来说,我想知道工作线程是如何分配给这个工作组的。线程数有默认值,还是机器核心数的函数?另外,关于上述问题,这些网络工作者如何与执行者合作?他们是否只处理 I/O - 对通道的读取和写入?

编辑:Netty,默认创建(2 * 核心数)工作线程。

【问题讨论】:

【参考方案1】:

您提供的Executor 是实际执行 rpc 回调的对象。这释放了EventLoop 以继续处理连接上的数据。当一条新消息从网络到达时,它会在事件循环中被读取,然后向上传播到堆栈到执行程序。执行程序获取消息并将它们传递给您的ServerCall.Listener,它实际上会处理数据。

默认情况下,gRPC 使用缓存线程池,因此非常容易上手。但是强烈建议您提供自己的执行人。原因是默认线程池在负载下表现不佳,在其余线程忙时创建新线程。

为了设置事件循环组,您在 NettyServerBuilder 上调用 workerEventLoopGroup 方法。 gRPC 并不严格依赖于 Netty(其他服务器传输也是可能的),因此必须使用特定于 Netty 的构建器。

【讨论】:

gRPC 是否有针对不同场景的推荐执行器,因为强烈建议不要使用默认值? 是的,使用固定大小的线程池。类似Executors.newFixedThreadPool(16) 感谢 Carl,这意味着如果我将单个实例 .addService(...) 添加到我的服务器并有多个线程分派请求,我的 *ServiceImplBase 应该是线程安全的? @user3833308 可以使用依赖注入框架轻松地从每个服务实现访问托管通道。 您通过使用 ServerInterceptor 传递 threadlocals,并附加/分离 io.grpc.Context。从附加的线程本地读取,并在分离时将其删除。

以上是关于grpc-java的ServerBuilder中executor的具体用途是啥?它只是执行处理程序方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

Grpc-java MacOS编译

grpc-java:正确处理客户端重试以进行服务流调用

苹果官方给 ARKit 开发者的 22 条建议;Google 高性能 RPC 框架 grpc-java 1.7.0 发布

gRPC服务端启动流程走查

protoc 不生成服务存根文件

Grpc应用场景