dubbo,作为一个成熟、易用、多支持的远程方法调用框架,应用广泛。为了透彻理解dubbo,我们今天来实现一把自己的dubbo。
为了实现dubbo,我们需要做哪些事情呢?
首先客户端与服务端的netty使用代码
服务端:
客户端:
方法调用转化为网络请求,此处不做aop实现,采用直接调用的形式(也就是aop拦截器中会做的事情)
如果从invoke开始直到拿到结果的过程中出错,怎么提示给客户端?我们将错误信息封装到RpcInfo中,在出现异常的时候,就将该对象写入到结果中。
但是netty的exceptionCaught方法是没有数据信息参数的,在返回异常信息的时候标示客户端请求的唯一id拿不到,怎么办?
很容易想到的一种方案是在服务端读到id信息之后就写入threadLocal中,之后exceptionCaught方法中从threadLocal取就好,笔者一开始也是这么想的,但是后来发现netty的handler链路不一定是在一个线程中:
所以需要加上对同一个请求handler链路跨越多个线程的支持,笔者的实现方案是在channelRead,write前后都加上try catch,这样就不会走到exceptionCaught中。
想到rpc实现比如dubbo可以增加许多用户自定义filter,也为了方便通过handler给本rpc实现添加更多的特征,将这部分代码进行了抽取,提取出一个ChannelHandlerAdapter基类,本实现中用到的ChannelHandlerAdapter都继承该基类(读取在反序列化之前,写操作在序列化之后的除外)。
接下来的就比较好理解了
客户端的handler
服务端端handler
代码详见:https://github.com/guzhangyu/practice-Code/tree/master/src/main/java/com/phei/netty/rpc