负载测试中出现gRPC UNAVAILABLE异常及请求延迟问题求助
问题描述
运行3-4次负载测试后,客户端抛出io.grpc.StatusRuntimeException: UNAVAILABLE: unavailable异常,且报错后的下一次请求耗时接近30秒。堆栈跟踪无Caused by信息:
io.grpc.StatusRuntimeException: UNAVAILABLE: unavailable at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:275) at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:256) at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:169) at co.com.mycompany.myappname.grpc.client.ValidateTransactionGrpc$ValidateTransactionBlockingStub.validate(ValidateTransactionGrpc.java:157) at co.com.mycompany.myappname.grpc.client.AppDetectorClient.invoke(AppDetectorClient.java:21) at co.com.mycompany.myappname.infrastructure.adapters.GrpcAdapter.provide(GrpcAdapter.java:33) at co.com.mycompany.myappname.application.services.AppDetectorService.execute(AppDetectorService.java:42) at co.com.mycompany.myappname.application.services.$AppDetectorService$Definition$Intercepted.$$access$$execute(Unknown Source) ...
环境配置:Java 11、Micronaut v3.9.1、所有gRPC相关组件版本均为1.49.0,已排查gRPC官方issue及服务端日志,未找到匹配解决方案。
排查与解决方向
客户端连接池耗尽/复用问题
Micronaut的gRPC客户端默认使用连接池,负载测试下易出现连接耗尽或死连接占用资源的情况。检查并调整micronaut.grpc.client.channel相关配置:- 增大
max-inbound-message-size和max-outbound-message-size,避免大消息阻塞连接 - 配置TCP保活参数,定期清理空闲死连接:
micronaut.grpc.client.keep-alive-time=30s micronaut.grpc.client.keep-alive-timeout=5s micronaut.grpc.client.keep-alive-without-calls=true
- 增大
超时配置缺失导致等待积压
报错后下一次请求耗时30秒,大概率是客户端在等待空闲连接或重试时触发了默认超时。给gRPC客户端设置明确的请求截止时间:ValidateTransactionBlockingStub stub = ValidateTransactionGrpc.newBlockingStub(channel) .withDeadlineAfter(5, TimeUnit.SECONDS);同时检查连接池的
max-pool-size和max-age配置,确保高峰时能及时释放过期连接。版本兼容性验证
Micronaut 3.9.1与gRPC 1.49.0可能存在隐性兼容问题,尝试升级gRPC到1.50+(需匹配Micronaut兼容版本),或降级到1.48.x稳定版本,验证问题是否复现。底层TCP连接排查
用tcpdump或Wireshark抓取负载测试时的网络包,检查是否存在TCP连接重置、丢包或延迟过高的情况。UNAVAILABLE异常很多时候是底层网络问题导致,而非gRPC逻辑错误。Micronaut线程池调整
负载测试下Micronaut处理gRPC请求的线程池可能耗尽,调整线程池配置:micronaut.executors.io.max-pool-size=200 micronaut.executors.io.core-pool-size=100
内容的提问来源于stack exchange,提问作者Camo Mola

