JAVA 中的 GRPC 服务器支持大量请求

GRPC server in JAVA to support huge load of requests

我在 java 上有一个 grpc (1.13.x) 服务器,它不执行任何计算或 I/O 密集型任务。目的是查看此服务器在80核机器上每秒可以支持的请求数。

服务器:

  ExecutorService executor = new ThreadPoolExecutor(160, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>(),
                new ThreadFactoryBuilder()
                        .setDaemon(true)
                        .setNameFormat("Glowroot-IT-Harness-GRPC-Executor-%d")
                        .build());
     Server server =  NettyServerBuilder.forPort(50051)
                .addService(new MyService())
                .executor(executor)
                .build()
                .start();

服务:

@Override
    public void verify(Request request, StreamObserver<Result> responseObserver) {
        Result result = Result.newBuilder()
                    .setMessage("hello")
                    .build();
        responseObserver.onNext(result);
        responseObserver.onCompleted();
    }

我正在使用 ghz 客户端执行负载测试。 服务器每秒能够处理 40k 个请求,但即使传入请求速率为 100k 的并发客户端数量增加,RPS​​ 计数也不能超过 40k。 GRPC 服务器每秒只能处理 40K 个请求,并将所有其他请求排队。 CPU 未得到充分利用 (7%)。尽管没有 I/O 操作,但大约 90% 的 grpc 线程(前缀为 grpc-default-executor)处于等待状态。超过 25k 个线程处于等待状态。

等待线程的堆栈跟踪:

grpc-default-executor-4605
PRIORITY :5

THREAD ID :0X00007F15A4440D80

NATIVE ID :
stackTrace:
java.lang.Thread.State: TIMED_WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@15.0.1/Native Method)
- parking to wait for <0x00007f1df161ae20> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(java.base@15.0.1/LockSupport.java:252)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(java.base@15.0.1/SynchronousQueue.java:462)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(java.base@15.0.1/SynchronousQueue.java:361)
at java.util.concurrent.SynchronousQueue.poll(java.base@15.0.1/SynchronousQueue.java:937)
at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@15.0.1/ThreadPoolExecutor.java:1055)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@15.0.1/ThreadPoolExecutor.java:1116)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@15.0.1/ThreadPoolExecutor.java:630)
at java.lang.Thread.run(java.base@15.0.1/Thread.java:832)
Locked ownable synchronizers:
- None

如何配置服务器以支持 100K+ 请求?

gRPC 堆栈中似乎没有任何内容会导致此限制。服务器端的平均响应时间是多少?看起来您受到临时端口或 TCP 连接限制的限制,您可能需要按照此处 https://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1 or here https://blog.box.com/ephemeral-port-exhaustion-and-web-services-at-scale

所述调整您的内核