# 《RPC手撸专栏》第13章:服务消费者异步转同步直接获取返回结果

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

大家好,我是冰河~~

我不想只在服务消费者的数据处理器中打印接收到的数据,我想调用服务消费者向服务提供者发送数据的方法,直接返回服务提供者调用真实方法的返回结果。

# 一、前言

目前你这个RPC框架只能在消费者处理器中打印结果数据,这不行啊,没法用!

在前面的章节中,我们重构了服务消费者的代码,使服务消费者对外屏蔽了基于Netty连接服务提供者的实现细节,开发人员不用再手动维护这些复杂的Netty代码了。

但是,还存在一个问题,就是在测试代码中调用服务消费者向服务提供者发送数据的方法时,不能直接获取到返回的结果数据。也就是说,目前在使用这个RPC框架时,外部调用服务消费者向服务提供者发送数据的方法时,无法获取到结果数据,只能在服务消费者的数据处理器类中的channelRead0()方法中打印服务提供者返回的结果数据。

这显然不符合一个RPC框架的需求,这部分,还要改。咋办?干就完了。。。

# 二、目标

别跟我扯别的,我就想调用方法时,直接返回结果!

一个好的RPC框架如果使用Java原生的方式调用远程方法时,要支持直接返回数据结果,就像下面的代码片段一样。

RpcConsumer consumer = RpcConsumer.getInstance();
Object result = consumer.sendRequest(rpcRequestProtocol);
LOGGER.info("从服务消费者获取到的数据===>>>" + result.toString());
consumer.close();
1
2
3
4

在使用Netty构建服务消费者和服务提供者时,服务消费者与服务提供者之间的交互本身是异步的,上面代码片段中调用consumer的sendRequest()方法时,很显然是在同步获取返回的结果数据,这就涉及到如何将异步调用转化为同步调用的问题了。咋办?撸起袖子干呗。

# 三、设计

如果是让你设计如何将服务消费者与服务提供者之间的交互由异步转化成同步,你会怎么设计?

RPC框架底层的数据通信依赖的是Netty,服务消费者与服务提供者之间进行数据交互时,本身是基于异步的方式进行的。这也是在前面的章节中为何在服务消费者向服务提供者发送数据后,只能在服务消费者的数据处理器类中打印结果数据,而不能在调用服务消费者发送数据的方法时,直接获取结果数据的原因。如图13-1所示。

图13-1 RPC框架异步发送数据的流程

由图13-1可以看出,目前实现的RPC框架中,服务消费者向服务提供者异步发送数据,并异步接收服务提供者响应的结果数据。这就会造成外部服务在调用服务消费者发送数据的方法时,无法直接获取到最终的结果数据。

需要重新设计服务消费者与服务提供者之间的数据交互过程,将外部服务调用服务消费者发送数据的方法,设计成等待服务消费者异步接收到服务提供者响应的结果数据后再返回,这样就能够在外部服务调用服务消费者发送数据的方法时,直接获取到返回的结果数据。如图13-2所示。

图13-2 异步转同步设计

由图13-2可以看出,进行异步转同步设计后,外部服务调用服务消费者的方法发送数据后,同步等待服务消费者接收到响应的数据后再返回,就能够实现立即获取到响应的结果数据。

# 四、实现

说了这么多,到底该如何实现呢?

# 查看完整文章

加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码