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的具体用途是啥?它只是执行处理程序方法吗?的主要内容,如果未能解决你的问题,请参考以下文章
苹果官方给 ARKit 开发者的 22 条建议;Google 高性能 RPC 框架 grpc-java 1.7.0 发布