# yuanyuan-rpc
**Repository Path**: yuantao99/yuanyuan-rpc
## Basic Information
- **Project Name**: yuanyuan-rpc
- **Description**: 自实现简单的rpc框架。通过对Spring框架的了解、序列化相关知识的学习,再利用dubbo、zookeeper等框架,实现了rpc框架的最基本原理。
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-09-07
- **Last Updated**: 2022-08-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Java, 序列化, rpc, 服务注册
## README
# yuanyuan-rpc
#### 介绍
自实现简单的rpc框架。
version 1.0:可以完成服务注册,服务发现,服务调用等基本功能。
version 1.1:完成一个使用例子,sample-client-demo模块远程调用sample-server-demo模块。
#### 软件架构
1. RPC 服务器(用于发布 RPC 服务):实现 `ApplicationContextAware`, `InitializingBean`。
1. `RpcServer`获取bean容器中`@RpcService`注解过的bean。
2. `RpcServer`初始化`afterPropertiesSet`方法中,启动netty服务器。读写拦截链中有`RpcDecoder`,`RpcEncoder`,`RpcServerHandler`。若有注册中心则将服务信息注册到服务中心中。
> `RpcServerHandler`处理流程是 `handle(RpcRequest)`获取`RpcResponse`返回结果并关闭连接通道。
>
> `handle(RpcRequest)`中调用远程服务为使用 CGLib 执行反射调用。
2. RPC客户端(用于发送 RPC 请求)
1. 创建并初始化 Netty 客户端。读写拦截链中有`RpcDecoder`,`RpcEncoder`,`RpcClientHeadler`。
2. 连接 RPC 服务器,写入 RPC 请求数据并关闭连接,返回 RPC 响应对象。
3. RPC 代理(用于创建 RPC 服务代理)
1. 创建代理的代理对象。代理对象封装请求,创建rpc客户端,发送请求给rpc服务器,获取并返回结果。
4. 基于zookeeper的服务注册中心
1. `register`注册方法创建 registry 节点(持久),创建 service 节点(持久),创建 address 节点(临时)。
> service 节点为服务名,address为服务地址。
2. `discover`服务发现方法,获取 service 节点,获取 address 节点,获取 address 节点的值。
#### 部分功能流程图
1. rpc服务发现、启动流程

2. rpc服务处理请求流程

#### 学习收获
1. `ApplicationContextAware`:当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。换句话说,就是这个类可以直接获取spring配置文件中,所有有引用到的bean对象。[link](https://www.jianshu.com/p/4c0723615a52)
2. `InitializingBean`:InitializingBean接口为bean提供了初始化方法的方式,它只包括`afterPropertiesSet`方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。[link](https://www.jianshu.com/p/f0af22d671a5)
3. [Apache Commons](https://commons.apache.org/)包是Java的工具包,它提供了我们常用的一些编程需要,但是JDK没能提供的机能,最大化的减少重复代码的编写。
4. [Objenesis ](http://objenesis.org/)是一个小型 Java 库,用于一个目的:**实例化特定类的新对象**。Java 已经支持使用`Class.newInstance()`。但是,这仅在类具有适当的构造函数时才有效。很多时候一个类不能用这种方式实例化,Objenesis 旨在通过绕过对象实例化的构造函数来克服这些限制。
5. 了解序列化,接触多种序列化协议,了解java多种序列化工具及框架。序列化:序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。
6. 了解netty,netty的整体架构及其使用。netty:[Netty](http://netty.io/) 是一个提供 asynchronous event-driven (异步事件驱动)的网络应用框架,是一个用以快速开发高性能、可扩展协议的服务器和客户端。
#### 笔记
1. [序列化笔记](https://gitee.com/yuantao99/note/blob/master/java/serialization.md)
2. [aop](https://gitee.com/yuantao99/note/blob/master/java/aop.md)
3. [spring ioc深入理解](https://gitee.com/yuantao99/note/blob/master/java/spring/spring-ioc.md)
4. [网络io的常见模型](https://gitee.com/yuantao99/note/blob/master/server/redis/03%20redis-work.md)
5. [netty笔记](https://gitee.com/yuantao99/note/blob/master/server/netty/netty.md)
6. [dubbo笔记](https://gitee.com/yuantao99/note/blob/master/microservice/dubbo/dubbo.md)
7. [zookeeper笔记](https://gitee.com/yuantao99/note/blob/master/microservice/zookeeper/zookeeper.md)
#### 安装
##### 生产组件
```xml
cn.yuanyuan.rpc
rpc-server
cn.yuanyuan.rpc
rpc-registry-zookeeper
cn.yuanyuan.rpc.demo
sample-api-demo
```
##### 消费组件
```xml
cn.yuanyuan.rpc
rpc-client
0.0.1-SNAPSHOT
cn.yuanyuan.rpc
rpc-registry-zookeeper
${project.version}
cn.yuanyuan.rpc.demo
sample-api-demo
0.0.1-SNAPSHOT
```
#### 软件使用
##### 注册服务
开启一个注册服务,如zookeeper中间件。
##### 生产组件
1. 配置文件
```properties
# rpc服务地址接口
rpc.service_address=127.0.0.1:8190
# 注册组件地址接口
rpc.registry_address=127.0.0.1:2181
```
2. @Configuration注解的类中创建bean。
```java
@Bean
public ServiceRegistry serviceRegistry() {
return new ZooKeeperServiceRegistry(REGISTRY_ADDRESS);
}
@Bean
public RpcServer rpcServer(ServiceRegistry serviceRegistry) {
return new RpcServer(SERVICE_ADDRESS, serviceRegistry);
}
```
##### 消费组件
1. 配置文件
```properties
# 注册组件地址接口
rpc.registry_address=127.0.0.1:2181
```
2. @Configuration注解的类中创建bean。
```java
@Bean
public ServiceDiscovery serviceDiscovery() {
return new ZooKeeperServiceDiscovery(REGISTRY_ADDRESS);
}
@Bean
public RpcProxy rpcProxy(ServiceDiscovery serviceDiscovery) {
return new RpcProxy(serviceDiscovery);
}
```
3. 代理需要进行rpc调用的类。
```java
@Bean
public HelloService helloService(RpcProxy rpcProxy) {
return rpcProxy.create(HelloService.class);
}
```
#### 阅读资料
1. [黄勇/rpc](https://gitee.com/huangyong/rpc)
2. [SnailClimb/guide-rpc-framework](https://gitee.com/SnailClimb/guide-rpc-framework)