大家好,我是小趴菜,接下来我会从0到1手写一个RPC框架,该专题包括以下专题,有兴趣的小伙伴就跟着我一起学习吧
本章源码地址:gitee.com/baojh123/se…
自定义注解 -> opt-01
服务提供者收发消息基础实现 -> opt-01
自定义网络传输协议的实现 -> opt-02
自定义编解码实现 -> opt-03
服务提供者调用真实方法实现 -> opt-04
完善服务消费者发送消息基础功能 -> opt-05
注册中心基础功能实现 -> opt-06
服务提供者整合注册中心 -> opt-07
服务消费者整合注册中心 -> opt-08
完善服务消费者接收响应结果 -> opt-09
服务消费者,服务提供者整合SpringBoot -> opt-10
动态代理屏蔽RPC服务调用底层细节 -> opt-10
SPI机制基础功能实现 -> opt-11
SPI机制扩展随机负载均衡策略 -> opt-12
SPI机制扩展轮询负载均衡策略 -> opt-13
SPI机制扩展JDK序列化 -> opt-14
SPI机制扩展JSON序列化 -> opt-15
SPI机制扩展protustuff序列化 -> opt-16
前言
在上一章中我们实现了服务端收发消息的基础功能,但是细心的同学会发现,我们使用的是Netty自带的String类型的网络传输协议。对于我们自己的RPC框架来说,这种协议不仅性能低下,而且无法扩展。
本章我们将实现我们自己的网络传输协议
设计
说到协议,我们首先会想到HTTP协议,TCP协议等, 以 HTTP协议为例,包括 请求头和 请求体
HTTP协议的请求头包含以下信息
- 请求地址:我们访问的资源目标地址
- 请求方法:GET,POST,DELETE等
- 状态:请求的状态码
- 请求时间:Date
- 请求体长度:Content-Length
- 请求类型:Content-Type
- ..........
HTTP协议的请求体包含以下信息
请求体就是包含我们这次请求的内容
其实我们可以按照HTTP协议的规则来设计我们自己的协议
实现
新建一个子项目 xpc-rpc-protocol,pom.xml文件如下
xpc-rpc
com.xpc
1.0-SNAPSHOT
4.0.0
xpc-rpc-protocol
既然我们的协议是类似HTTP协议的,那么请求也要包括请求头和 请求体
请求头实现 com.xpc.rpc.protocol.header.RpcHeader
package com.xpc.rpc.protocol.header;
/**
* 请求头
*/
public class RpcHeader {
/**
* 请求类型,是普通请求,或者是心跳消息等
*/
private String msgType;
/**
* 消息体的长度
*/
private int bodyLen;
/**
* 请求的唯一ID
*/
private Long requestId;
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
public int getBodyLen() {
return bodyLen;
}
public void setBodyLen(int bodyLen) {
this.bodyLen = bodyLen;
}
public Long getRequestId() {
return requestId;
}
public void setRequestId(Long requestId) {
this.requestId = requestId;
}
}
- msgType:请求消息的类型,比如这个请求是普通的请求,就是服务消费者调用服务提供者接口的请求。或者是这个请求是响应请求。还有后续会实现的心跳消息等等
- bodyLen:请求体数据的长度
- requestId:这次请求的唯一标识,全局唯一
请求体实现 com.xpc.rpc.protocol.request.RpcRequest
package com.xpc.rpc.protocol.request;
import com.xpc.rpc.protocol.header.RpcHeader;
/**
* RPC请求体
*/
public class RpcRequest{
/**
* 类名称
*/
private String className;
/**
* 方法名称
*/
private String methodName;
/**
* 参数类型数组
*/
private Class[] parameterTypes;
/**
* 参数数组
*/
private Object[] parameters;
public RpcHeader getRpcHeader() {
return rpcHeader;
}
public void setRpcHeader(RpcHeader rpcHeader) {
this.rpcHeader = rpcHeader;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Class[] getParameterTypes() {
return parameterTypes;
}
public void setParameterTypes(Class[] parameterTypes) {
this.parameterTypes = parameterTypes;
}
public Object[] getParameters() {
return parameters;
}
public void setParameters(Object[] parameters) {
this.parameters = parameters;
}
}
- className:服务提供者的类名称
- methodName:这次请求调用的方法
- parameterTypes:方法参数的类型数组
- parameters:方法参数数组
响应体实现 com.xpc.rpc.protocol.response.RpcResponse
package com.xpc.rpc.protocol.response;
import com.xpc.rpc.protocol.header.RpcHeader;
/**
* RPC响应体
*/
public class RpcResponse {
/**
* 响应数据
*/
private T data;
/**
* 错误信息
*/
private String errMsg;
/**
* 响应状态码
*/
private Integer code;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
- T:服务消费者调用服务提供者接口,服务提供者接口返回的数据
- errMsg:如果请求发生异常,返回异常信息
- code:响应状态码
传输协议 com.xpc.rpc.protocol.ProtocolMessage
package com.xpc.rpc.protocol;
import com.xpc.rpc.protocol.header.RpcHeader;
/**
* 自定义网络传输协议
*/
public class ProtocolMessage {
private T t;
private RpcHeader rpcHeader;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public RpcHeader getRpcHeader() {
return rpcHeader;
}
public void setRpcHeader(RpcHeader rpcHeader) {
this.rpcHeader = rpcHeader;
}
}
- T:RpcRequest或者是RpcResponse
- RpcHeader:请求头或者是响应头
结尾
本章我们就实现了自定义的网络传输协议的设计,下一章我们就会使用自定义的协议了来进行网络传输