Tag - "RPC"
2020
自己动手实现一个RPC框架(五)
2020 年 03 月 25 日
rpc-transport 这个模块是有在观看消息队列高手课中的rpc示例完成的。
网络传输模块,这里使用netty来进行实现。
生产者调用来指定端口启动服务。
1 2 3 4 public interface TransportServer { void start(int port) throws InterruptedException; void stop(); }
自己动手实现一个RPC框架(四)
2020 年 03 月 25 日
rpc-register 注册中心,这里使用zookeeper来实现。
生产者在启动服务时,将自己实现的服务注册到注册中心。
消费者调用服务时,来注册中心查找,返回调用服务实例的地址信息。
并且为了适应不同的注册实现,我们将功能定义为接口,在替换实现时在配置文件中进行替换即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public interface RpcRegister { /** * 注册服务 * @param serviceDescriptor * @param responseServiceDescription */ void register(ServiceDescriptor serviceDescriptor, ResponseServiceDescription responseServiceDescription); /** * 根据服务名称查询实例地址 * @param serviceDescriptor * @return */ ResponseServiceDescription lookup(ServiceDescriptor serviceDescriptor); }
自己动手实现一个RPC框架(三)
2020 年 03 月 25 日
rpc-commons 这个模块主要是定义一些通信协议类,工具类。
自己动手实现一个RPC框架(七)
2020 年 03 月 25 日
rpc-client 消费者端,通过代理来进行调用。
与生产者端类型,首先定义配置类:
1 2 3 4 5 6 7 8 9 10 public class ClientConfig { private Class<? extends Encoder> encoder = FastJsonEncoder.class; private Class<? extends Decoder> decoder = FastJsonDecoder.class; private Class<? extends TransportClient> transportClient = NettyClient.class; private Class<? extends RpcRegister> rpcRegister = ZookeeperRegistry.class; }
自己动手实现一个RPC框架(六)
2020 年 03 月 25 日
rpc-server 消费者的部分,这里使用配置类,将各种实现的部分在配置类中进行定义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ServerConfig { /** * 监听端口 */ private int port = 9090; /** * 网络传输 */ private Class<? extends TransportServer> transportClass = NettyServer.class; /** * 注册中心 */ private Class<? extends RpcRegister> rpcRegister = ZookeeperRegistry.class; /** * 编码 */ private Class<? extends Encoder> encoder = FastJsonEncoder.class; /** * 解码 */ private Class<? extends Decoder> decoder = FastJsonDecoder.class; } 这这个配置中,定义了服务启动的端口,网络传输,注册中心,编解码的各种实现,当我们需要更换实现时只需要在这里修改即可。
自己动手实现一个RPC框架(二)
2020 年 03 月 25 日
自己动手实现一个RPC框架
使用fastjson,netty,反射,动态代理,zookeeper实现一个RPC框架。
代码链接:https://github.com/liunaijie/self-rpc-framwork`
各模块说明: rpc-commons 通用设置模块,包括网络传输的数据格式,请求编号工具类,反射工具类等一些底层协议,工具相关的内容
rpc-register
服务注册模块,主要包括服务的注册与发现功能。这里使用zookeeper来进行实现。
在这里,服务端注册时,使用通用模块中的ServiceDescriptor,ResponseServiceDescription类来进行注册 ResponseServiceDescription类是ServiceDescription的子类,添加了实现类,实例地址等属性。 消费者查找服务时,发送ServiceDescription得到ResponseServiceDescription,一个类可能有多个实现类,多个实例,在返回时进行随机返回。 对于同一个实现的不同版本实现,或多个服务实例这种情况随机返回没有问题。对于不同实现类,采用随机返回可能有些问题,但是在spring中对于多实现类也需要指定实现类,所以后面再考虑更改。
自己动手实现一个RPC框架(一)
2020 年 03 月 12 日
前言 现在微服务体系流行,而RPC框架作为微服务中重要的一环,为了弄明白RPC的整体过程,决定要自己动手实现一个RPC框架。
我们先了解一下什么是RPC,RPC全程是Remote Procedure Call,翻译过来就是远程过程调用,我们先思考一下没有使用rpc的项目的调用流程:
通过@Autoware注解注入另外的类 在需要调用的地方直接调用即可 当需要调用其他功能的接口时,比如调用其他公司的接口,或者调用自己公司内部的其他业务或功能接口。这时一般需要使用http来进行网络调用。
那么使用http调用其他的功能接口算不算是rpc调用呢?我感觉也是算的,因为这也是一种通过网络从计算机程序上请求服务的过程。
只不过由于调用的功能不严格意义上属于一个大项目,所以不算一个程序直接的内部调用,所以这里只讨论 一个大项目拆分成不同模块后,不同模块直接调用的过程。
RPC是原来一个程序分为多个不同的程序,分别运行在不同的jvm上。部署在多台机器上后,就涉及到网络通信,需要将调用的信息发送到被调用的机器上,调用完成后再进行返回。
rpc的流程图如下所示,
牵扯到网络请求,那么就可以使用之前的http请求,但是由于http请求需要封装一些对于我们而言无用的信息,所以使用http的方式可以采用,比如springcloud就采用了http来进行通信的方式,而这次我准备使用其他的网络通信方式,这一篇中先使用bio来实现网络通信。
还有一个序列化过程,它主要是将信息进行编解码,然后通过网络传输,因为网络传输中都是传输的二进制字节码文件,所以我们需要定义规则,将信息进行转换,消费者发送出去的信息生产者能明白其调用的内容,消费者也能明白生产者返回的信息。这一篇文章中也不去使用复杂的序列化方式,直接实现java中的Serializable接口。
2019
手写rpc简单实现
2019 年 07 月 26 日
背景 当单体项目逐渐扩大后,一个项目编译,发布可能需要很久的时间,如果其中一个文件出现 bug,那么需要对整个项目进行打包发布。微服务就是对项目进行拆分,拆分成多个小项目,由这些小项目组成大项目。并且拆分成小项目后,其他单体项目中需要相同功能的地方就不用再次编写,直接用这个就可以了。有种分治的思想。
那么原来单体项目拆分后,随之而来就会出现一些问题。原来一个项目中直接调用即可,现在请求的类被拆分到其他项目中,如何进行请求,是采用 http 这种请求还是rpc?多个模块如果进行管理等等一系列问题。这里主要写一下 rpc 的理解。
在微服务中rpc又是重要的一环,现在主流的rpc框架有很多,比如阿里的dubbo,微博的Motan,谷歌的gRpc,还有Thrift,现在主流的应该就这几种吧。按照文档学习了一下dubbo如何使用后,发现并没有了解rpc是如何具体实现的。所以这篇文章记录了自己对rpc的一些理解与实战代码。
代码链接
HTTP 与 RPC 的对比 其实就像一些技术一样,没有绝对好的技术,不然大家都去使用它了。都只是在不同场景下有各自的优势。
rpc一般是自带负载均衡策略,而 http 一般是通过 nginx 这种来实现负载均衡 rpc可以使用 tcp 协议也可以使用 http 协议,而 http 就只能使用 http 协议 rpc可以自定义传输信息和序列化方法,减少传输报文大小。 所以RPC主要用于公司内部的服务调用。HTTP主要用于对外的环境,浏览器接口调用,APP接口调用,第三方接口调用等。
RPC的主要实现步骤