手动实现一款轻量高效的分布式RPC框架
一、概述
手动实现一款轻量,高效的RPC框架,基于TCP的二进制协议实现
二、特征
- 基于netty的主从Reactor模型,NIO通信
- 支持同步,异步,携带回调等调用方式
- 支持spring项目下引入starter包开箱即用,整合spring,实现服务接口透明使用
三、设计
可能对RPC框架性能产生影响的几个因素:
四、使用示例
4.1、spring环境下
maven依赖
<dependency> <groupId>com.hex</groupId> <artifactId>srpc-spring-boot-starter</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>com.hex</groupId> <artifactId>srpc-registry-zookeeper</artifactId> <version>1.1.0</version> </dependency> @SRpcClient(nodes = {"127.0.0.1:9955","127.0.0.1:9956","127.0.0.1:9957"}) public interface HelloService { String hello(String name); } @SRpcRoute public class HelloServiceImpl implements HelloService { @Override public String hello(String name) { return name + " Hey bro, it's a good day"; } } @ConfigurationProperties(prefix = "srpc.server") public class RpcServerProperties { private Integer port = 9957; //绑定端口 private Integer businessThreads = 200; //业务处理线程池大小,0为不设置 private Integer businessQueueSize = 500; //业务线程池队列大小 private Integer connectionIdleTime = 180;//超过连接空闲时间(秒)未收发数据则关闭连接 private Integer printConnectionNumInterval = 0; //打印服务端当前连接详情, 时间间隔(秒), 0为不打印 private Boolean isPrintHearBeatPacketInfo = false; //是否打印心跳包信息 private CompressType compressType = CompressType.SNAPPY; //压缩算法类型,无需压缩为NONE private SerializeType serializeType = SerializeType.PROTOSTUFF; //序列化类型,默认protostuff private Integer sendBuf = 65535; //tcp发送缓冲区 private Integer receiveBuf = 65535; //tcp接收缓冲区 private Integer lowWaterLevel = 1024 * 1024; //netty低水位 private Integer highWaterLevel = 10 * 1024 * 1024; //netty高水位 private boolean deDuplicateEnable = false; //是否开启去重处理 private Integer duplicateCheckTime = 10; //请求去重缓存时长(秒) private Long duplicateMaxSize = 1024 * 64L; //最大缓存请求个数 private Boolean trafficMonitorEnable = false; //是否开启流控 private Long maxReadSpeed = 10 * 1000 * 1000L; //带宽限制,最大读取速度 private Long maxWriteSpeed = 10 * 1000 * 1000L; //带宽限制,最大写出速度 // ----tls加密部分配置 private Boolean useTLS = false; //是否开启tls加密 private String keyPath; //私钥文件路径 private String keyPwd; //密码 private String certPath; //证书文件路径 private String trustCertPath; //受信任ca证书路径 private String clientAuth; //是否要求客户端认证 // ----注册中心配置部分 private Boolean enableRegistry = false; //是否使用注册中心 private String registrySchema; //注册中心模式名称 private List<String> registryAddress; //注册中心地址 @ConfigurationProperties(prefix = "srpc.client") public class RpcClientProperties { private Integer callBackTaskThreads = 200; //回调任务处理线程池大小,0为不设置 private Integer callBackTaskQueueSize = 500; //回调任务线程池队列大小 private Integer connectionTimeout = 5; //连接超时时间(秒) private Integer requestTimeout = 10; //请求超时时间(秒) private Integer connectionSizePerNode = 3; //每个节点连接数 private Integer connectionIdleTime = 180; //超过连接空闲时间(秒)未收发数据则关闭连接 private Integer heartBeatTimeInterval = 30; //发送心跳包间隔时间(秒) private CompressType compressType = CompressType.SNAPPY; //压缩算法类型,无需压缩为NONE private SerializeType serializeType = SerializeType.PROTOSTUFF; //序列化类型,默认protostuff private LoadBalanceRule loadBalanceRule = LoadBalanceRule.RANDOM; //集群负载均衡策略 private boolean excludeUnAvailableNodesEnable = true; //集群模式下是否排除不可用的节点 private Integer nodeErrorTimes = 3; //节点连接或请求超时/异常超过设置次数则置为节点不可用 private Integer nodeHealthCheckTimeInterval = 10; //节点健康检查周期(秒),心跳包响应成功则恢复不可用的节点 private Integer sendBuf = 65535; //tcp发送缓冲区 private Integer receiveBuf = 65535; //tcp接收缓冲区 private Integer lowWaterLevel = 1024 * 1024; //netty低水位 private Integer highWaterLevel = 10 * 1024 * 1024; //netty高水位 private Boolean trafficMonitorEnable = false; //是否开启流量控制 private Long maxReadSpeed = 10 * 1000 * 1000L; //带宽限制,最大读取速度 private Long maxWriteSpeed = 10 * 1000 * 1000L; //带宽限制,最大写出速度 // ----TLS加密部分配置 private Boolean useTLS = false; //是否开启TLS加密 private String keyPath; //私钥文件路径 private String keyPwd; //密码 private String certPath; //证书文件路径 private String trustCertPath; //受信任ca证书路径 private String clientAuth; //是否要求客户端认证 // ----注册中心配置部分 private Boolean enableRegistry = false; //是否使用注册中心 private String registrySchema; //注册中心模式名称, 缺省为zookeeper private List<String> registryAddress; //注册中心地址 @Component public class HelloRpcTest { @Autowired private HelloService helloService; // 上面定义的rpc服务接口 public void rpcServerTest(String name) { String msg = helloService.hello(name); System.out.println(msg); } }