文章目录
如何设计一个RPC协议?
在上面的需求描述中我们知道,RPC非常重要的一环,就是自己制定符合自己需求的通信协议,这里,我简单的列出了我的协议。
public class RpcHeader implements Serializable {
//public static final long serialVersionUID = 200201141215L;
//当前RPC服务版本号(借鉴Dubbo)
private byte versionId;
//使用的序列化/压缩算法
private byte algorithmType;
//请求类型
private byte reqType;
//请求ID
private long reqId;
//消息内容长度
private int length;
}
//RPC DTO对象
//是项目最终使用的数据传输对象
@Data
public class RpcDto<T> implements Serializable {
//请求头
private RpcHeader header;
//数据
private T data;
}
协议的实现比较简单,但是,那些设计的非常良好的开源框架,也会在协议上下很多功夫,来尽可能保证使用的协议传输快,性能好,空间浪费少。
这里我简单的列出一个对协议的优化方式。
比如我们知道,对于algorithmType这个字段,使用byte类型能最多提供8bit,也就是最多256种不同方式。
那么,其实单纯的使用一个byte,我们就能同时表示出要使用的序列化算法和压缩等算法,也就是用位运算这种方法,能够充分的解决空间的浪费问题同时位运算性能也很高。
具体设计方式如下:
package blossom.project.rpc.common.enums;
/**
* @author: ZhangBlossom
* @date: 2023/12/16 16:55
* @contact: QQ:4602197553
* @contact: WX:qczjhczs0114
* @blog: https://blog.csdn.net/Zhangsama1
* @github: https://github.com/ZhangBlossom
* AlgorithmTypeEnum类
* 一个字节8个bit 0000 | 0000
* 2^4 = 16 也就是高低位分别可以对应16种数据
* 1:可以高位用于存放压缩算法
* 2:低位存储序列化算法
* 3:使用位运算进行高低位计算即可得到具体的算法类型
*/
public enum AlgorithmTypeEnum {
// 压缩算法枚举定义
NO_COMPRESSION((byte)0x00), // 无压缩(默认操作,这样子就算不选也无所谓了)
GZIP((byte)0x10), // GZIP压缩
// ... 其他压缩算法
// 序列化算法枚举定义
PROTOBUF((byte)0x01), // Protobuf序列化
ARVO((byte)0x02), // Avro序列化
JSON((byte)0x03), // JSON序列化
JAVA((byte)0x04); // Java原生序列化
private byte code;
AlgorithmTypeEnum(byte code) {
this.code = code;
}
public byte getCode() {
return this.code;
}
// 结合压缩算法和序列化算法的code
public static byte combine(AlgorithmTypeEnum compression, AlgorithmTypeEnum serialization) {
return (byte) (compression.code | serialization.code);
}
// 分离组合code为压缩和序列化算法的code
public static AlgorithmTypeEnum[] split(byte combinedCode) {
byte compressionCode = (byte) (combinedCode & 0xF0); // 获取高4位
byte serializationCode = (byte) (combinedCode & 0x0F); // 获取低4位
return new AlgorithmTypeEnum[]{
findByCode(compressionCode), // 压缩算法
findByCode(serializationCode) // 序列化算法
};
}
// 根据code查找对应的枚举值
private static AlgorithmTypeEnum findByCode(byte code) {
for (AlgorithmTypeEnum type : AlgorithmTypeEnum.values()) {
if (type.code == code) {
return type;
}
}
//没有找到对应的枚举类型就报错
throw new RuntimeException("No enumeration type was found");
}
}
然,在协议上还有很多功夫可以去琢磨,我就不细扣了。
标签:AlgorithmTypeEnum,code,自定义,BlossomRPC,RPC,private,byte,序列化,public From: https://blog.csdn.net/Zhangsama1/article/details/137184316