【发布时间】:2020-03-26 09:50:38
【问题描述】:
我遇到了一个非常奇怪的问题:基本上,我在 java 中实现了一个服务器流式传输 grpc 客户端,并且我使用微配置文件作为库/结构。当涉及到自动重试和回退时,Microprofiles 有非常方便的拦截器,但它依赖于在拦截注释函数中抛出的异常,否则重试不会被触发。
对于非单一的 grpc 调用,这工作得很好,它的工作方式与普通的 REST 调用非常相似。但是当将客户端创建到 grpc 服务器端流时,protobuf 将创建它自己的线程并请求回调来处理 onNext、onError 和 onCompleted。所以当在流作用域内调用 onError 时,抛出的任何异常都不会被发送回用于启动流的任何函数,因此不会抛出任何异常来触发@Retry。
无法更改异步流的处理方式,也无法更改@Retry 的触发方式。 grpc是生成代码,@Retry触发器是基于microprofile库的。
例子:
@Retry(
retryOn = {IOException.class, TimeoutException.class, StatusRuntimeException.class},
maxDuration = 10,
durationUnit = ChronoUnit.SECONDS,
maxRetries = 1,
delay = 10,
delayUnit = ChronoUnit.SECONDS
)
public void subscribeToLocations() {
// --> Throwing an exception here triggers the @Retry <--
SubscribeRequest locSubscribeRequest = SubscribeRequest.newBuilder().build();
streamObserver = grpcStreamHandler();
grpcBlockingstub.subscribeServerStreaming(locSubscribeRequest, streamObserver); // Can't change this.
}
private StreamObserver<SubscribeResponse> grpcStreamHandler() {
return new StreamObserver<SubscribeResponse>() {
@Override
public void onNext(SubscribeResponse value) {
// Handle grpc response
}
@Override
public void onError(Throwable t) {
// --> ERROR: Here, it should trigger the @Retry somehow. <--
}
@Override
public void onCompleted() {
// Handle oncomplete
}
};
}
我试图找到解决方案的时间比我想承认的要长,但我仍然不知所措。有没有办法在一个范围内抛出异常,最终在另一个范围内?还有其他解决办法吗?
【问题讨论】:
标签: java java-ee-6 grpc-java microprofile