一.概述
什么是RPC?
- 远程服务调用
- 官方:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的思想
- 通俗一点:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。
- 市面上常见的rpc框架:dobbo,springCloud,gRPC...
那为什么要有 RPC,HTTP 不好么?
- 因为 RPC 和 HTTP 就不是一个层级的东西,所以严格意义上这两个没有可比性,也不应该来作比较。
- HTTP 只是传输协议,协议只是规范了一定的交流格式
- RPC 对比的是本地过程调用,是用来作为分布式系统之间的通信,它可以用 HTTP 来传输,也可以基于 TCP 自定义协议传输。
- HTTP 协议比较冗余,所以 RPC 大多都是基于 TCP 自定义协议,定制化的才是最适合自己的。
项目总体结构
整体架构
接下来,分别解释上述的过程
二.自定义注解
服务的提供者和消费者公用一个接口,@ServiceExpose是为了暴露服务,放在生产者的某个实现类上;@ServiceReference是为了引用服务,放在消费者的需要注入的属性上。
- Target:指定被修饰的Annotation可以放置的位置(被修饰的目标)
- @Target(ElementType.TYPE) //接口、类
- @Target(ElementType.FIELD) //属性
- @Target(ElementType.METHOD) //方法
- @Target(ElementType.PARAMETER) //方法参数
- @Target(ElementType.CONSTRUCTOR) //构造函数
- @Target(ElementType.LOCAL_VARIABLE) //局部变量
- @Target(ElementType.ANNOTATION_TYPE) //注解
- @Target(ElementType.PACKAGE) //包
- Retention:定义注解的保留策略
- @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
- @Retention(RetentionPolicy.CLASS) //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
- @Retention(RetentionPolicy.RUNTIME) //注解会在class字节码文件中存在,在运行时可以通过反射获取到
- Documented:指定被修饰的该Annotation可以被javadoc工具提取成文档
- Inherited:指定被修饰的Annotation将具有继承性
二.启动配置
主要是加载一些rpc相关的配置类,使用SpringBoot自动装配。可以使用SPI机制加入一些自定义的类,放到指定文件夹中。
三.rpc接口注入/rpc服务扫描
这里主要就是通过反射获得对应注解的属性/类,进行服务暴露/服务引用。 这里需要关注的是什么时候进行服务暴露/引用?如下:
- 客户端:一般有俩种方案
- 饿汉式:饿汉式是通过实现 Spring 的InitializingBean接口中的 afterPropertiesSet方法,容器通过调用 ReferenceBean的 afterPropertiesSet