gRPC接口返回多响应报错:Too many responses问题排查求助
解决gRPC "Too many responses" 错误并实现服务器流式响应
问题根源
你当前的gRPC API定义的是普通RPC(Unary RPC),这种模式要求服务器只能返回一个响应,但你的代码里调用了5次responseObserver.onNext(),违反了gRPC的规则,因此触发Too many responses内部错误,同时客户端因未收到预期的单响应而持续加载。
解决方案
要实现"一个请求对应多个间隔响应"的需求,需要将接口改为服务器流式RPC,并调整代码实现逻辑:
1. 修改Proto定义为服务器流式RPC
在返回类型前添加stream关键字,明确告知gRPC这是一个流式接口:
rpc test(google.protobuf.Empty) returns (stream MyString); message MyString { string value = 1; }
2. 调整Java实现代码(异步非阻塞流式处理)
之前的代码用Mono.block()会阻塞线程,且循环创建多个Mono的方式不符合流式响应的最佳实践。改用Flux生成异步流,优雅实现间隔发送:
public void test(Empty request, StreamObserver<MyString> responseObserver) { Flux.range(1, 5) .delayElements(Duration.ofSeconds(2)) // 按你的预期设置2秒间隔 .map(i -> MyString.newBuilder().setValue("Value " + i).build()) .doOnNext(responseObserver::onNext) .doOnComplete(responseObserver::onCompleted) .doOnError(responseObserver::onError) .subscribe(); }
代码说明
Flux.range(1,5)生成1到5的整数序列delayElements控制每个元素的发送间隔map将整数转换为MyString对象doOnNext把每个元素通过responseObserver.onNext()发送给客户端doOnComplete在所有元素发送完毕后调用onCompleted(),告知客户端流结束subscribe()触发整个流的异步执行,避免阻塞线程
修改完成后,客户端(如BloomRPC)就能正确接收5个间隔2秒的流式响应,不会再出现Too many responses错误。
内容的提问来源于stack exchange,提问作者Capitano Giovarco
相关产品推荐
相关产品推荐

