一款基于Netty
+Zookeeper
+Spring
实现的轻量级Java RPC
框架。提供服务注册,发现,负载均衡,支持API
调用,Spring
集成和Spring Boot starter
使用。是一个学习RPC
工作原理的良好示例。
通过这个简易项目的学习,可以让你从零开始实现一个类似 Dubbo
服务框架 mini 版RPC
,学到 RPC
的底层原理以及各种 Java
编码实践的运用。下面看一下RPC
的调用流程:
Easy-rpc框架
├─easy-rpc-core --rpc核心实现类
├─easy-rpc-spring-starter --组件的spring-starter接入类
├─rpc-framework-consumer --[示例]服务消费者
├─rpc-framework-interface --存放服务接口
└─rpc-framework-provider --[示例]服务提供者
- 简单易学的代码和框架,在代码中含有大量注解
- 基于
Netty
实现长连接通信,包括心跳检测、解决粘包半包等 - 基于
Zookeeper
实现分布式服务注册与发现 - 实现了轮询、随机、加权随机等负载均衡算法
- 实现了同步调用、异步调用多种调用方式
- 支持
jdk
、javassist
的动态代理方式 - 支持
fastJson
、hessian
、kryo
、jdk
的序列化方式 - 支持简易扩展点,泛化调用等功能
- 加入了
Spring Boot Starter
easy-rpc
框架调用流程:
- 代理层:负责对底层调用细节的封装;
- 链路层:负责执行一些自定义的过滤链路,可以供后期二次扩展;
- 路由层:负责在集群目标服务中的调用筛选策略;
- 协议层:负责请求数据的转码封装等作用;
- 注册中心:关注服务的上下线,以及一些权重,配置动态调整等功能;
- 容错层:当服务调用出现失败之后需要有容错层的兜底辅助;
- JDK8 或以上
- Maven 3
- Zookeeper 单机或者集群实例
方式一:使用本项目中的测试用例
-
将项目克隆到本地
git clone git@github.com:shaogezhu/easy-rpc.git
-
IDEA打开项目
使用 IDEA 打开,等待项目初始化完成。
-
运行`Zookeeper
如果没有安装的过需要先去下载。
-
修改配置文件
修改客户端和服务端
rpc.properties
配置文件中zookeeper的地址(配置文件中位默的地址为127.0.0.1:2181
) -
启动项目(按照图中顺序)
PS:启动项目前,要确保
zookeeper
已启动.
-
打开浏览器测试
在浏览器中输入
http://localhost:8081/user/test
或者http://localhost:8081/user/list
,然后查看项目的输出日志。
方式二:将该rpc
框架运用到自己项目中
-
下载源码
git clone git@github.com:shaogezhu/easy-rpc.git
-
编译安装 jar 包到本地仓库(注意如果是服务器上面,需要上传到私服仓库)
mvn clean install
-
新建
Spring Boot Maven
工程在本地新建两个工程,用于模拟客户端和服务端。
-
引入入依赖
在项目中的
pom
引入刚刚安装的依赖(客户端、服务端都需要引入)<dependency> <groupId>com.shaogezhu</groupId> <artifactId>easy-rpc-spring-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
-
定义服务接口
/** * @Author peng * @Date 2023/2/25 * @description: 自定义的测试类 */ public interface DataService { /** * 发送数据 * @param msg 内容 * @return 服务端消息 */ String sendData(String msg); }
-
实现接口,使用自定义注解
@EasyRpcService
暴露一个服务接口/** * @Author peng * @Date 2023/3/11 * @description: 实现类 */ @EasyRpcService public class DataServiceImpl implements DataService { @Override public String sendData(String body) { System.out.println("这里是服务提供者,body is " + body); return "success from server"; } }
-
服务端配置
在服务端模块的
resource
文件夹下新建rpc.properties
文件,并加入以下配置#服务端对外暴露的端口 rpc.serverPort=8010 #项目名称 rpc.applicationName=rpc-provider #注册中心(zookeeper)的地址 rpc.registerAddr=127.0.0.1:2181 #注册中心类型 rpc.registerType=zookeeper #序列化方式 rpc.serverSerialize=fastJson
-
使用自定义注解
@EasyRpcReference
自动注入服务端暴露的接口服务@RestController @RequestMapping(value = "/data") public class DataController { @EasyRpcReference private DataService dataService; @GetMapping(value = "/send/{msg}") public String sendMsg(@PathVariable(name = "msg") String msg){ return dataService.sendData(msg); } }
-
客户端配置
在客户端模块的
resource
文件夹下新建rpc.properties
文件,并加入以下配置#项目名称 rpc.applicationName=rpc-consumer #注册中心(zookeeper)的地址 rpc.registerAddr=127.0.0.1:2181 #注册中心类型 rpc.registerType=zookeeper #代理方式(jdk、javassist) rpc.proxyType=jdk #路由策略(负载均衡) rpc.router=random #客户端序列化方式 rpc.clientSerialize=fastJson
-
启动项目
首先启动服务端(服务提供者),再启动客户端(服务消费者)。
-
测试
打开浏览器,输入
http://localhost:8081/user/send/helloworld
。有字符串返回就说明运行成功。
1、zookeeper
连接失败
解决方法:
(1)在本地机器或者在服务器上安装运行 zookeeper
实例;
(2)在配置文件中正确配置 zookeeper
地址;
感谢DannyIdea(小林)老师,在这个项目中给了我很大启发和帮助🚀🚀🚀。
💝 如果觉得这个项目对你有帮助,可点击右上角Watch、Star项目,获取项目第一时间更新,欢迎提交Issues和PR项目。