我们正在使用GRPC与我们的一种微服务进行对话。在大多数情况下,微服务抛出的 StatusRuntimeException
会正确地传回并由客户端在 try/catch
块中捕获。
但是,在这些GRPC请求的极小部分(处于高负载时),似乎没有遵守 catch
块,而是引发了异常。奇怪的是,当它冒泡时,堆栈跟踪( io.grpc.StatusRuntimeException
)中报告的异常与catch块( { {1}} )。因此,由于某种原因它没有被io.grpc.StatusRuntimeException
块捕获吗?
这是堆栈跟踪中的例外(请注意对第191行的引用):
catch
这是我们的try / catch块(请注意,第191行在try块中,并且正在捕获stacktrace中报告的相同类型的异常):
[2018-12-03 18:16:48,653] WARN[{2018-12-03 18:16:48} SF: /edam/intern] com.xxx.PersistentStore.invoke(PersistentStore.java:485)
- Unexpected invocation exception in persistent store method getBusinessUserProfilesWithPhotoFlag
>>> io.grpc.StatusRuntimeException: <<< NOT_FOUND: user profile photo metadata not found
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:227)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:208)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:141)
at com.xxx.UPPServiceGrpc$UppServiceBlockingStub.getMetadata(UppServiceGrpc.java:312)
at com.xxx.UppMicroserviceClient.getMetadata(UppMicroserviceClient.java:68)
at >>> com.xxx.UppMicroserviceImpl.getMetadata(UppMicroserviceImpl.java:191) <<
at com.xxx.UppMicroserviceImpl.lambda$getUserIdsWithPhotos$5(UppMicroserviceImpl.java:356)
同样,此代码在大量的大多数调用中都能正常工作,但是少量请求似乎会生成具有相同功能的GRPC编组 import io.grpc.StatusRuntimeException;
public Optional<UserProfilePhotoMetadata> getMetadata(int userId) {
...
try {
191: GetMetadataResponse response = uppClient.getMetadata(request);
...
return toUserProfilePhotoMetadata(response.getPhotoMetadata());
195: } catch (StatusRuntimeException e) {
String errorCode = e.getStatus().getCode().name();
if (ENConfig.isUserProfilePhotoMetricsEnabled()) {
addFailureMetrics("getMetadata", errorCode);
}
return Optional.empty();
...
对象包说明符作为StatusRuntimeException
块中指定的类型,但显然在二进制级别上是不相同。
现在,我们在客户端/微服务上使用的GRPC版本略有不同,但是我们检查了catch
类上的SerialVersionIDs
,它们的值相同。我们甚至尝试提高GRPC的版本以使其匹配,但问题并没有消失。
有没有其他人看到过这个原因,或者不知道原因可能是什么?已经提出了一些类加载器问题,但尚未得到验证。