【发布时间】:2021-05-01 02:39:33
【问题描述】:
我需要在 java 中实现一个 grpc 服务器,它能够处理 grpc 一元和双向流。使用 grpc bidi-streaming 的服务可以发送大量每秒消息数。(可能每秒 2000 条消息或更多)我有两种实现方式,有点困惑哪一种最适合我的要求。
1.为 grpc 一元和 grpc 双向使用相同的服务器。
当使用这种方法时,由于grpc unary 和bidi stream 使用相同的端口,一个boss thread 将被分配给unary 和bidi stream。所以我不确定在双向流每秒接收大量消息的情况下它的性能如何。 (我的意思是老板线程是否会忙于双向流而变得不可用一元)
final EventLoopGroup bossGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors());
final EventLoopGroup workerGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2);
int blockingQueueLength = 1000;
final BlockingQueue blockingQueue = new LinkedBlockingQueue(blockingQueueLength);
final Executor executor = new ThreadPoolExecutor(400, 500, 30, TimeUnit.SECONDS, blockingQueue);
Server server = NettyServerBuilder.forPort(PORT).maxConcurrentCallsPerConnection(50)
.keepAliveTime(60, TimeUnit.SECONDS).bossEventLoopGroup(bossGroup)
.workerEventLoopGroup(workerGroup).addService(new ExtAuthService()).addService(new RateLimitService())
.channelType(NioServerSocketChannel.class)
.executor(executor).build();
try{
server.start();
erver.awaitTermination();
}catch(Exception e){
Logger.Error("Execption", new Error(e));
}
2。使用两台服务器,一台用于 grpc 一元,一台用于 grpc 双向流。
这里不存在前面提到的问题,因为我们为每个 grpc 一元和双向流分配了 2 个老板线程。但是对于我使用的服务,我使用了一个使用 java ThreadPoolExecutor 的执行器,我的问题是 我应该为使用 grpc 一元和双向流的两个服务使用 2 个线程池吗?
final EventLoopGroup bossGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors());
final EventLoopGroup workerGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2);
int blockingQueueLength = 1000;
final BlockingQueue blockingQueue = new LinkedBlockingQueue(blockingQueueLength);
final Executor executor = new ThreadPoolExecutor(400, 500, 30, TimeUnit.SECONDS, blockingQueue);
// I have used here the same executor for both servers.
Server server1 = NettyServerBuilder.forPort(PORT_1).maxConcurrentCallsPerConnection(50)
.keepAliveTime(60, TimeUnit.SECONDS).bossEventLoopGroup(bossGroup)
.workerEventLoopGroup(workerGroup).addService(new ExtAuthService())
.channelType(NioServerSocketChannel.class)
.executor(executor).build();
Server server2 = NettyServerBuilder.forPort(PORT_2).maxConcurrentCallsPerConnection(50)
.keepAliveTime(60, TimeUnit.SECONDS).bossEventLoopGroup(bossGroup)
.workerEventLoopGroup(workerGroup).addService(new RateLimitService())
.channelType(NioServerSocketChannel.class)
.executor(executor).build();
try{
server1.start();
server2.start();
server1.awaitTermination();
server2.awaitTermination();
}catch(Exception e){
Logger.Error("Execption", new Error(e));
}
【问题讨论】:
-
您是否考虑过针对这两种实现编写任何压力测试?
-
是的,想过这样做,但没有时间这样做。会做一些性能测试,看看。
-
@drfloob 但我想这更像是一个常见的用例。所以应该有一个标准的方法来做到这一点?
标签: java netty grpc http2 grpc-java