
手把手实现RPC框架--简易版Dubbo构造
文章平均质量分 71
”PANDA
努力是最不值得被炫耀的东西
展开
-
手把手实现RPC框架--简易版Dubbo构造(一)项目初始化
rpc-api文件夹:服务端与客户端的公共调用接口 rpc-common文件夹:项目中的一些通用的枚举类和工具类 rpc-core文件夹:框架的核心实现 test-client文件夹:测试用的客户端项目 test-server文件夹:测试用的服务端项目...原创 2021-02-03 19:49:25 · 3511 阅读 · 0 评论 -
手把手实现RPC框架--简易版Dubbo构造(二)从一个简单实现开始
本节commit源码地址:ca82236盗一张Guide哥的图哈我们首先要思考,RPC框架的原理:原理其实很简单,客户端和服务端都可以访问到通用的接口,但是只有服务端有这个接口的实现类,客户端调用这个接口的方式,是通过网络传输,告诉服务端我要调用这个接口,服务端收到之后找到这个接口的实现类,并且执行,将执行的结果返回给客户端,客户端拿到返回的结果,结束。我们先进行最基本的实现,然后一步一步完善,假设我们现在知道服务端的地址,尝试来实现一下这个过程。API通用接口定义接口public i原创 2021-02-03 21:27:28 · 2710 阅读 · 0 评论 -
手把手实现RPC框架--简易版Dubbo构造(三)客户端动态代理
本节commit源码地址:416bb92客户端实现(动态代理)由于在客户端这边我们并没有接口的具体实现类,就没有办法直接生成实例对象。这时,我们可以通过JDK动态代理的方式生成实例。(关于动态代理不太熟的小伙伴可以戳:动态代理详解)public class RpcClientProxy implements InvocationHandler { private String host; private int port; //传递host和port来指明服原创 2021-02-04 23:12:56 · 2478 阅读 · 9 评论 -
手把手实现RPC框架--简易版Dubbo构造(四)服务端线程池处理请求 反射调用
本节commit源码地址:11e4aca服务端实现--反射调用从服务端接如果收到请求就创建一个线程来处理调用,利用线程池创建线程,对多线程情况进行处理(Java线程池学习请戳:https://blog.youkuaiyun.com/suifeng3051/article/details/49443835)public class RpcServer { private final ExecutorService threadPool; private static final Logge原创 2021-02-06 18:18:34 · 2201 阅读 · 10 评论 -
手把手实现RPC框架--简易版Dubbo构造(五)让服务器提供多个服务
首先对上一阶段的源码进行了重构优化,增加了自定义异常处理,commit地址:f8a3acc在前面的小节中我们设计的是服务器默认只提供一个服务,本节就来探讨如何让服务器提供多个服务本节commit地址:8b71c6d服务注册表我们需要一个容器,用来保存服务端提供的所有服务,方便查询使用,即通过服务名字就能返回这个服务的具体信息(利用接口名字获取到具体接口实现类对象)。创建一个 ServiceRegistry 接口:public interface ServiceRegistry {原创 2021-02-18 16:41:03 · 1763 阅读 · 2 评论 -
手把手实现RPC框架--简易版Dubbo构造(六)项目结构调整 为引入Netty做准备
本节commit地址:b3d9814我们之前一直使用的BIO方式传输,接下来将会转为效率更高的NIO方式,但不会使用 Java 原生的 NIO,而是采用更为简单的 Netty。因此在引入Netty前需要对项目结构和源码进行重新调整,以区分开之前的Socket,实现多种方式传输。为了保证通用性,我们可以把 Server 和 Client 抽象成两个接口,分别是 RpcServer 和 RpcClient:public interface RpcServer { void start(in原创 2021-02-18 21:53:23 · 1628 阅读 · 0 评论 -
手把手实现RPC框架--简易版Dubbo构造(七)netty传输与通用序列化接口实现
本节commit源码地址:0e68adb本篇内容较多,本人花了较多时间在Netty学习上面,所以更新时间间隔拉的长了点,对Netty运行的全过程进行了总结,同时对Netty部分的代码逐行进行了注释,学习本节前建议可以先看下:netty全过程图解接下来进入正题Netty服务端public class NettyServer implements RpcServer { private static final Logger logger = LoggerFactory.getLogg.原创 2021-03-02 19:42:23 · 2831 阅读 · 9 评论 -
手把手实现RPC框架--简易版Dubbo构造(八)Kryo序列化
本节commit地址:f16b1f2 上一节中,主要实现了Netty传输,以及基于Jackson的序列化器,但通过使用也发现存在一个问题,Json进行反序列化时,如果某个类的属性声明是Object类型,就会造成反序列化出错,通常会把Object属性直接反序列化成String类型,此时就需要其他参数辅助反序列化。同时,JSON序列化器是基于字符串(JSON串)的,占用空间较大且速度较慢。 因此本节利用Kryo来实现序列化,Kryo是一个快速高效的Java对象序列化框架,主要特点是...原创 2021-03-09 22:31:21 · 1483 阅读 · 1 评论 -
手把手实现RPC框架--简易版Dubbo构造(九)Hessian序列化、线程池工具
本节commit地址:1ed2159上一节我们实现了Kryo序列化,抱着学习的心态,本节基于Hessian协议来实现序列化,实现步骤和之前的Kryo类似,关于Hessian和Kryo的区别可以参考另一篇:https://blog.youkuaiyun.com/qq_38685503/article/details/114633168?spm=1001.2014.3001.5501本节还会把线程池封装成一个通用Util,要用到guava中的ThreadFactoryBuilder(),自定义线程名,方便出错定位问题原创 2021-03-10 19:13:23 · 1459 阅读 · 0 评论 -
手把手实现RPC框架--简易版Dubbo构造(十)Netty连接失败重试机制、Protostuff序列化器
为了让结构更清晰一点,本节将分成几次内容提交。统一Socket与Netty传输协议,同时让Socket使用序列化器commit地址:bdb7dc4还记得在之前的Socket传输中,我们并未引入传输协议,只是单纯传输了一个RpcRequest对象给服务端,直接使用Java原生的readObject、writeObject就可以完成传输,不需要单独的序列化器,现在我们希望让Socket与Netty使用的传输协议保持一致,这意味着Socket也要用到序列化器,通过对代码的重构,实现了在TestServe原创 2021-03-12 19:57:50 · 2096 阅读 · 0 评论 -
手把手实现RPC框架--简易版Dubbo构造(十一)服务注册中心Nacos
本节commit地址: 8136649(由于引入Nacos,项目结构和代码调整较大,头莫被搞昏了,但理解起来简单)为什么需要Nacos?我们现在的RPC框架其实只有一个服务提供者,客户端也是通过固定的一个服务端地址进行访问的,这会存在极大的隐患,如果这个服务提供者挂了或者换了地址,那客户端就没法访问了。在分布式架构中,有一个重要的组件,就是服务注册中心,它用于保存多个服务提供者的信息,每个服务提供者在启动时都需要向注册中心注册自己所拥有的服务。这样客户端在发起远程调用的时候,就可以直接向注册中心请原创 2021-03-13 21:38:47 · 2389 阅读 · 4 评论 -
手把手实现RPC框架--简易版Dubbo构造(十二)实现注销服务的钩子、优化线程池
本节分成三次提交。将服务注册与服务实现分开commit地址:5128986在上一节中我们实现了Nacos服务注册中心,为了让逻辑更清晰,现在将Nacos相关操作都放在NacosUtil工具类: public class NacosUtil { 21 22 private static final Logger logger = LoggerFactory.getLogger(NacosUtil.class); 23 24 private static fin原创 2021-03-14 21:44:46 · 1728 阅读 · 0 评论 -
手把手实现RPC框架--简易版Dubbo构造(十三)Netty心跳机制、实现服务负载均衡
本节依然分成三次提交。Netty心跳机制什么是心跳机制:https://blog.youkuaiyun.com/u013967175/article/details/78591810Netty对心跳机制有两个层面实现,第一个是TCP层面,之前给通道初始化设置的值.option(ChannelOption.SO_KEEPALIVE, true) 就是TCP的心跳机制,第二个层面是通过通道中的处理IdleStateHandler来实现,可以自定义心跳检测间隔时长,以及具体检测的逻辑实现。首先是客户端的心跳.原创 2021-03-15 19:35:58 · 2525 阅读 · 13 评论 -
手把手实现RPC框架--简易版Dubbo构造(十四)服务端自动注册服务
本节commit地址: ec8defe到目前为止,客户端已经差不多了,但是在服务端,我们却还需要手动创建服务对象,并且手动进行注册,如果服务端提供了很多服务,这个操作就会变得很繁琐。本节就会介绍如何基于注解进行服务的自动注册。定义注解首先定义Service注解,用来标识一个服务提供类,注解放在Impl类上://表示注解的作用目标为接口、类、枚举类型@Target(ElementType.TYPE)//表示在运行时可以动态获取注解信息@Retention(RetentionPolicy原创 2021-03-16 15:54:07 · 2317 阅读 · 1 评论