Java实现RPC框架 - 2 最基础的RPC实现(动态代理)

前言

做RPC的思路,是从最基本的逐渐升级成一个方便可用的RPC框架。
所以我觉得一股脑把优化过程中用到的技术都倒出来并不利于学习。还是逐步升级,用了什么技术再去了解。在迭代过程中把每次迭代需要的技术点写在前面,方便学习。

本次考虑最基本的最容易想到的情况,即远程发消息调用一个固定的方法。就类似于做算法题要先考虑暴力算法,再去进行优化。

需要的技术

  • netty/nio/socket网络编程
  • 动态代理

最简单的RPC

我们服务端有一个UserService接口,有一方法getUserById(Integer id)。
实现类UserServiceImpl实现了接口方法。
我们目标是客户端请求服务端调用该方法并把结果返回给客户端。

这里我们自己已经知道要调什么方法,所以我们可以接收到客户端传来的ID后直接调用该方法(当然,后续升级要调用什么方法应该由客户端决定,然后服务端调用对应方法。而不是我们在代码写死调用一个固定方法)。

我们很容易实现这个需求。
利用Socket,NIO或者Netty,实现一个客户端和一个服务端。通过IP建立客户端服务端连接,客户端发送要查的ID,服务端接收后去调用对应方法查出结果User对象并发送给客户端。客户端通过readObject()接收到object对象,强转为User`。
只要你学过网络编程相信不是很难写。

那么这样基础的RPC,很明显是权宜之计。有哪些可以优化的地方呢?

优化点

我们捋一下思路,整个过程是,客户端发起请求request,服务端接收请求并处理,封装结果返回给客户端,客户端接收并处理。

既然是请求-响应的网络传输,我们需要定义合适的请求与响应。我们考虑上面的请求和响应,十分简陋,来看看需要优化的点:

  • 这种实现只能调用一个我们写死的方法,因为我们只带了执行的参数,没有指定方法。若服务端有多个方法,我们该执行哪个?(request不只需要参数,还需要指定接口,方法)
  • 返回值也写死了,需要强转为User。并且response不包含状态码(无法像http那样返回一个值来表示本次执行是否成功)

除了request和response不够完备的问题,还有一个问题
我们的目的是想本地调用一样进行远程调用。但是上面那种写法不符合这个要求
我们上面那种写法,大量的服务端客户端代码暴露在外,但其实通信过程可以封装到内部。我们需要类似于本地调用的形式:
注入接口实现,直接调用方法。

public class Myclient {  
  
    @Autowired  
    private MyService myService;  
  
    public void doSomething() {  
        myService.performAction();  
    }  
}

但是这是RPC,我们只有这一个接口,是没有它的实现的,所以我们通过发起远程调用的方式来进行方法的调用。也就意味着再RPC中我们用网络通信发起请求并获得结果这一过程替换了本地调用中的直接调用。简言之,就是通过网络进行远程调用替换了本地调用。所以我们的目标就明确了。因为本地没有实现类,所以我们给出一个实现类,在实现类中做远程调用中的一系列通信流程不就好了吗。所以目标是生产该接口的动态代理类(这个代理类实现方法执行后应该与本地方法调用结果一致,但是过程却从本地变为远程调用),代理类中做好远程调用并获取结果这件事。这样我们在进行远程调用时不就类似本地调用了吗。

总结一下优化点:

  • 请求与响应封装好对象
  • 使用动态代理完成透明的RPC

封装好请求响应,做好动态代理后有哪些地方还可以优化

结语

本文代码还没整理完,整理完了会贴上来。

不必基于一口气知道最终的RPC实现的功能。在开发过程中去寻求优化逐步发掘需要的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值