C++基于muduo库从零实现Rpc框架
RPC项目的gitee连接供大家参考:https://gitee.com/yang-weidong123/rpc
一、认识 Rpc
RPC(Remote Procedure Call)远程过程调用,是⼀种通过网络从远程计算机上请求服务,而不需要了解底层网络络通信细节。RPC可以使用多种网络协议进行通信, 如HTTP、TCP、UDP等, 并且在 TCP/IP网络四层模型中跨越了传输层和应用层。简言之RPC就是像调用本地方法⼀样调用远程方法。 过程可以理解为业务处理、计算任务,更直白的说,就是程序/方法/函数等,就是像调用本地方法⼀样调用远程方法。
Rpc的大致通信框架(Rpc如何工作的原理框架)
在这里给大家解释一下这个框架的原理,也就是客户端在本地调用方法接口,但是由于本地的方法的算力太小无法给我们一个答案,所以通过网络协议模块构建一个请求通过网络接口发送到远端的具有强大算力的服务器上,在远端的服务器上通过网络接口接收这个请求然后解析出来客户端请求的方法和参数,然后再服务端进行调用方法很快取得应答,然后再构造应答发送给客户端,客户端再进行对这个应答的解析,拿出最终的结果,这就是一个完整的Rpc调用的过程。由于网络通信很快,所以客户端感觉不到是在调用远端具有高强力的服务器,而是感觉在调用本地的算力方法,因此才有像调用本地方法⼀样调用远程方法的说法。
二、项目实现过程
通过这个Rpc项目可以学到:
1、序列化协议:因为在进行网络通信的时候为了防止粘包问题,消息不足问题需要我们对发送的报文进行序列化在进行发送,对方收到消息之后需要进行反序列化才可以拿到正确的消息。在这里我也自定义了一个LV格式的协议来进行对报文进行序列化和反序列化,具体LV格式如下图:
2、通信协议:这里采用Tcp/Udp都是可以的,这里我选择Tcp通信的方式。
3、连接复用:这里采用长连接来实现连接复用,因为短连接的话,效率不高,每次请求都要创建一个新的连接,请求完之后又要删除这个连接,所以这里我采用长连接,可以一直使用,更加方便,效率高一点。
4、服务注册:这里就是给服务中心注册服务,客户端在请求服务的时候如果这个服务有的话才会被调用成功,没有的话就客户端就无法调用这个服务了。
5、服务发现:客户端在请求一个服务的时候,如果没有直接发现这个服务,就给服务中心发送服务发现报文请求,询问服务中心有没有提供这个服务的主机,如果有就返回对应服务所对应的ip和端口供客户端连接去访问服务。
6、主题订阅与推送:这个模块客户端可以通过订阅主题,主题推送的消息就可以推送给订阅对应主题的客户端。
7、负载均衡:负载均衡一般有三种路由策略(随机、轮询、哈希), 由客户端使用,在客户端实现负载均衡,这里我们使用轮询的方式进行负载均衡。
8、异步、同步、函数回调调用:这里我们用C++11库中提供的 future 对象来帮助我们进行异步,同步的获取应答的结果,函数回调方法是通过收到服务端的应答之后,我们通过对应答调用回调函数来处理应答的结果。
这里将所有的功能模块进行整合之后,绘制出了一幅我们这个项目的总的操作功能图。
扩展功能(后续需要的话会进行实现):
1、实现负载上报系统:可以帮我们获取每个服务被调用的情况信息,为后续维护Rpc打基础。
2、实现服务心跳检查,超时管理:可以通过减少心跳检查的时间来释放一些一直不访问的连接,减少资源消耗,等过一段时间再次发送请求时重新建立连接。
3、扩展发布订阅的转发策略:这个项目中实现的发布订阅模块功能简单,只有一个对订阅者的消息推送功能,后续需要进行优化的话可以再加功能进去。
三、总结
1、这次我们底层通信方式采用的时陈硕大佬所实现的muduo库,简化了我们进行网络通信的过程,如果后面大家需要对这个底层的网络通信方式进行替换可以直接替换通信方式,因为底层我们通过基类来对这个网络通信方式进行描述,替换掉继承网络底层通信的类即可做到替换,这个Rpc项目仍然可以被使用。
2、这个项目自定义的通信协议是通过用Json库来实现的,因为这样更加简单方便实现对消息的序列化和反序列化。
3、本框架为使用者提供了快速构建分布式服务的能力。使用者可方便地启动注册中心,搭建服务集群,自动服务注册、发现,自动负载均衡。
通过上面所讲解的内容可能大家也会有点不理解的地方,大家可以通过去阅读Rpc项目的代码及注释去了解更多的细节,以上就是这个项目的主要内容供大家参考。