一、概述手动实现一款轻量,高效的RPC框架,基于TCP的二进制协议实现
github源码:
https://github.com/wosn00/srpc
二、特征
- 基于netty的主从Reactor模型,NIO通信
- 支持同步,异步,携带回调等调用方式
- 支持spring项目下引入starter包开箱即用,整合spring,实现服务接口透明使用
- 支持非spring项目下单独使用,可不依赖spring环境
- 支持多种序列化类型,Protostuff,Kryo,Json,Jdk等
- 支持多种压缩算法,SnAppy,Lz4,gzip,bzip2,Deflate,Lzo等
- 支持注册中心,自动服务注册和发现,默认实现zookpeer,也可不使用注册中心,手动指定服务端节点地址列表
- 支持多种负载均衡策略,随机,轮询,一致性hash等
- 支持服务容错,连接/调用异常情况下自动排除服务端故障节点
- 支持SPI扩展点,可扩展负载均衡策略,压缩算法,序列化类型,线程池,注册中心等
- 支持TLS双向认证加密
- 支持流量整形,请求异常重试,服务端请求去重等功能

文章插图
可能对RPC框架性能产生影响的几个因素:
- 网络IO线程模型
- 通信协议设计
- 序列化性能
- 服务调用管理方式
- 连接池的维护

文章插图
协议上设计尽量紧凑,4位bit用于标识序列化类型,压缩类型和指令类型,方法映射上不需要像dubbo那样传输完整的类 方法 参数信息导致的无用流量增大,而是自行生成对应rpc调用方法的唯一标识字符串
3.2 同步线程模型

文章插图
3.3 异步线程模型

文章插图
四、使用示例
4.1、spring环境下maven依赖
<dependency><groupId>com.hex</groupId><artifactId>srpc-spring-boot-starter</artifactId><version>1.1.0</version></dependency>若需使用zookeeper作为注册中心则引入<dependency><groupId>com.hex</groupId><artifactId>srpc-registry-zookeeper</artifactId><version>1.1.0</version></dependency>server端使用【手动实现一款轻量 高效的分布式RPC框架】1.定义服务接口@SRpcClient(serviceName = "testService")public interface HelloService {String hello(String name);}接口添加@SRpcClient注解,serviceName属性为rpc服务都在注册中心的服务名称,若不使用注册中心,则注解nodes属性需手动指定服务端节点集群地址,将根据负载均衡策略自动选取节点调用@SRpcClient(nodes = {"127.0.0.1:9955","127.0.0.1:9956","127.0.0.1:9957"})public interface HelloService {String hello(String name);}2.服务接口实现@SRpcRoutepublic class HelloServiceImpl implements HelloService {@Overridepublic String hello(String name) {return name + " Hey bro, it's a good day";}}实现类添加@SRpcRoute注解,便会自动注册为spring的单例bean,可视为等同@Comphonent使用,内部可用@Autowired等spring相关注解,也可被其他bean注入 。3.配置yml
因同时包含了rpc客户端和服务端,所以客户端和服务端都需要配置,如需个性化配置的地方在yml或properties文件按需配置即可,以srpc.server或srpc.client为前缀 。所有可自由配置的选项如下
服务端默认配置:
@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; //压缩算法类型,无需压缩为NONEprivate SerializeType serializeType = SerializeType.PROTOSTUFF; //序列化类型,默认protostuffprivate 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; //注册中心地址
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 专门做计划的软件?有没有一款计划软件_1
- 为梦想努力拼搏作文?拼搏实现梦想作文
- 一款非常实用的屏幕截图工具
- 手把手教你用python实现自动登录
- 简单分析实现运维利器---web远程ssh终端录像回放
- windows AD域_如何实现企业AD域高效,高质管理?
- 无线模块如何实现低功耗
- Linux内核时钟系统和定时器实现
- plc定时器工作过程?plc如何应用定时器实现长时间的定时
- 四大网络抓包神器,总有一款适合你
