Gatling测试gRPC双向流无响应且超时,请求排查帮助
Gatling测试gRPC双向流无法获取响应,触发DEADLINE_EXCEEDED问题排查
我在用Gatling测试gRPC双向流(bidiStream)时,发送请求后拿不到响应,没法确认流是否正常运行。测试脚本如下:
val paymentFinalizerProcess_Message = (session: io.gatling.core.session.Session) => { val PaymentCustomize = Payment( //body ) val paymentResultCustomize = PaymentResult( //body ) PaymentFinalizerRequest( //body ) } val PaymentFinalizerProcess_Call = grpc("BIDIStream") .bidiStream[PaymentFinalizerRequest, PaymentFinalizerHandlingResponse](RelayServerGrpc.METHOD_PAYMENT_FINALIZER_PROCESS, "PaymentFinalizerProcess") val speaker = scenario("PaymentFinalizerProcess") .exec( PaymentFinalizerProcess_Call .connect .header(Authorization)(s"Bearer string") .callOptions(CallOptions.DEFAULT.withDeadlineAfter(30, TimeUnit.SECONDS)) .endCheck(statusCode is Status.Code.DEADLINE_EXCEEDED) ) .exec( PaymentFinalizerProcess_Call .send(paymentFinalizerProcess_Message) ) .exec(PaymentFinalizerProcess_Call.reconciliate(waitFor = StreamEnd)) setUp( speaker.inject( atOnceUsers(1) ) ).protocols(grpcConf) }
原本以为是日志级别不够,把logback.xml的root级别改成WARN没变化,改成TRACE还是看不到响应流日志。simulation.log记录如下:
RUN test.scala.PaymentFinalizerProcess paymentfinalizerprocess 1698283070288 3.9.0 USER PaymentFinalizerProcess START 1698283071010 REQUEST BIDIStream 1698283070849 1698283100857 OK USER PaymentFinalizerProcess END 1698283100874
Gatling运行日志显示最终触发DEADLINE_EXCEEDED状态,我的logback.xml配置位于src/test/resources,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern> </encoder> <immediateFlush>false</immediateFlush> </appender> <!-- uncomment and set to DEBUG to log all failing HTTP requests --> <!-- uncomment and set to TRACE to log all HTTP requests --> <!--<logger name="io.gatling.http.engine.response" level="TRACE" />--> <!-- uncomment to log WebSocket events --> <logger name="io.gatling.http.action.ws.fsm" level="TRACE" /> <!-- uncomment to log SSE events --> <logger name="io.gatling.http.action.sse.fsm" level="TRACE" /> <root level="TRACE"> <appender-ref ref="CONSOLE" /> </root> </configuration>
排查思路与解决方法
1. 脚本逻辑修正
- 移除错误的connect阶段检查:你在
connect步骤中设置了.endCheck(statusCode is Status.Code.DEADLINE_EXCEEDED),这会强制Gatling等待连接阶段触发超时才继续后续操作——但双向流的connect仅建立连接,不会立即结束,导致后续的send操作在超时后才执行,此时流已经关闭,自然拿不到响应。要么移除该检查,要么改为检查成功状态:.endCheck(statusCode is Status.Code.OK)。 - 调整流操作顺序:确保
connect建立连接后,立即执行send发送消息,再通过reconciliate等待响应或流结束。 - 适配
reconciliate的等待逻辑:如果服务端不会主动关闭流,不要用waitFor = StreamEnd,改用waitFor = SomeMessage并定义响应匹配条件,避免无限等待超时。
修正后的示例脚本:
val paymentFinalizerProcess_Message = (session: io.gatling.core.session.Session) => { val PaymentCustomize = Payment( // body内容 ) val paymentResultCustomize = PaymentResult( // body内容 ) PaymentFinalizerRequest( // body内容 ) } val PaymentFinalizerProcess_Call = grpc("BIDIStream") .bidiStream[PaymentFinalizerRequest, PaymentFinalizerHandlingResponse](RelayServerGrpc.METHOD_PAYMENT_FINALIZER_PROCESS, "PaymentFinalizerProcess") val speaker = scenario("PaymentFinalizerProcess") .exec( PaymentFinalizerProcess_Call .connect .header(Authorization)(s"Bearer string") .callOptions(CallOptions.DEFAULT.withDeadlineAfter(30, TimeUnit.SECONDS)) .endCheck(statusCode is Status.Code.OK) ) .exec( PaymentFinalizerProcess_Call .send(paymentFinalizerProcess_Message) ) .exec( PaymentFinalizerProcess_Call .reconciliate(waitFor = SomeMessage(response => /* 自定义响应匹配逻辑 */)) ) setUp( speaker.inject(atOnceUsers(1)) ).protocols(grpcConf)
2. 日志配置优化
当前logback未开启gRPC相关日志,添加以下配置即可查看流交互细节:
<!-- 开启Gatling gRPC模块日志 --> <logger name="io.gatling.grpc" level="TRACE" /> <!-- 开启gRPC底层通信日志 --> <logger name="io.grpc.netty" level="DEBUG" />
3. 服务端与网络排查
- 检查服务端日志,确认是否收到并处理了Gatling发送的请求,有无内部错误;
- 验证Gatling所在机器与gRPC服务端的网络连通性,排除防火墙、代理拦截;
- 评估30秒Deadline是否合理,若服务端处理耗时较长,适当延长超时时间。
内容的提问来源于stack exchange,提问作者TriNguyen
相关产品推荐
相关产品推荐

