1.背景
今天在做开发,一个业务功能需要做异步调用。正好想到Hrpc框架(公司自己封装的Grpc)已经做好了封装,但是其有两种方式,一个是future(),一个是asyn()。
因此,通过调试探讨了两者的区别。
2.Future方式
下面是一个demo测试,其实future最重要的是这句话。
responseFuture.get(30, TimeUnit.SECONDS)
这个相当于,A调用B服务,然后不等待B返回结果,而是过一段时间A主动去查询改调用的返回结果。
@Test
public void testDeviceQueryBySnFuture() {
// rpc 请求参数
DeviceQueryBySnRequest request = DeviceQueryBySnRequest.newBuilder().build();
try {
// 执行 rpc 方法
ListenableFuture<DeviceQueryBySnResponse> responseFuture = deviceGrpcServiceClient.future().deviceQueryBySn(request);
DeviceQueryBySnResponse response = responseFuture.get(30, TimeUnit.SECONDS);
LOGGER.info("deviceGrpcServiceClient.future().deviceQueryBySn() success: {}", response);
} catch (Exception ex) {
LOGGER.error("deviceGrpcServiceClient.future().deviceQueryBySn() error:", ex);
fail();
}
}
3.Async方式
async方式最重要的是这句话。
deviceGrpcServiceClient.async().deviceQueryBySn(request, requestParams, asyncListenner);
可以看到async是调用时,把执行完该调用要做的回调方法都传入进去,也就是通过增加回调函数的方式来调用。
@Test
public void testDeviceQueryBySnAsync() {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final AtomicReference<DeviceQueryBySnResponse> replyAtomicReference = new AtomicReference<>();
// rpc 回调
StreamObserver<DeviceQueryBySnResponse> asyncListenner = AsyncListennerBuilder.newBuilder(DeviceQueryBySnResponse.class)
.onSuccess((response) -> {
countDownLatch.countDown();
replyAtomicReference.set((DeviceQueryBySnResponse) response);
LOGGER.info("deviceGrpcServiceClient.async().deviceQueryBySn() success: {}", response);
})
.onError((throwable) -> {
countDownLatch.countDown();
LOGGER.error("deviceGrpcServiceClient.async().deviceQueryBySn() error:", throwable);
})
.onCompleted(() -> {
countDownLatch.countDown();
LOGGER.info("deviceGrpcServiceClient.async().deviceQueryBySn() complete");
})
.build();
try {
// rpc 调用参数
RequestParams requestParams = new RequestParams();
requestParams.setDeadlineMS(30000L);
requestParams.setGzip(true);
// rpc 请求参数
DeviceQueryBySnRequest request = DeviceQueryBySnRequest.newBuilder().build();
// 执行 rpc 方法
deviceGrpcServiceClient.async().deviceQueryBySn(request, requestParams, asyncListenner);
countDownLatch.await();
assertNotNull(replyAtomicReference.get());
} catch (Exception ex) {
LOGGER.error("deviceGrpcServiceClient.async().deviceQueryBySn() error:", ex);
fail();
}
4.总结
- future 是过一段时间去查询调用结果,然后执行相关内容。
- async 是增加回调函数,执行完调用自动执行回调。
以上纯属个人见解,如有误,欢迎指正。