• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

    QSRPC-starter: 一个基于QSRPC,结合spring-boot实现远程调用的轻量级高性能RPC框架 ...

    原作者: [db:作者] 来自: 网络 收藏 邀请

    开源软件名称:

    QSRPC-starter

    开源软件地址:

    https://gitee.com/sakaue/QSRPC-starter

    开源软件介绍:

    logo

    一个基于QSRPC, 结合 spring-boot 实现远程调用的轻量级高性能RPC框架

    star QSRPC License

    • 使用 nacos(2.0) / zookeeper 服务发现, 自动注册扩展服务
    • 使用长连接TCP池, netty 作为网络IO, 支持全双工通信, 高性能
    • 支持异步调用,提升qps上限
    • 默认使用 Protostuff 序列化
    • 支持压缩snappy, gzip
    • 支持针对整个服务/单个接口进行qps限制, 超时等设置
    • 支持权重调用服务负载均衡
    • 欢迎学习交流~

    Maven

    <dependency>    <groupId>com.github.tohodog</groupId>    <artifactId>qsrpc-starter</artifactId>    <version>1.1.1</version></dependency><!--导入如有问题,可尝试添加jitpack源--><repositories>  <repository>      <id>jitpack.io</id>      <url>https://jitpack.io</url>  </repository></repositories>

    Demo(4step)

    First configurednacos/zookeeper

    1.application.properties(yml)

    #nacos qsrpc.nacos.addr=192.168.0.100:8848#zookeeper #qsrpc.zk.ips=127.0.0.1:2181#节点IPqsrpc.node.ip=192.168.0.100 (请配置为内(外)网IP,不配置自动获取)qsrpc.node.port=19980#option#请求权重(1-127) 默认平均1#qsrpc.node.weight=1#压缩,带宽不足可选#qsrpc.node.zip=snappy/gzip#全局请求超时时间#qsrpc.connect.timeout=60000

    2.SpringBootApplication

    @EnableQSRpc//add this//@EnableQSRpc(qps = 100000) 限制整个服务qps@SpringBootApplicationpublic class RPCApplication {    public static void main(String[] args) {        SpringApplication.run(RPCApplication.class, args);    }}

    3.public api

    public interface IRPCServer {    String hello(String name);    RPCFuture<String> future(String name);//异步}

    4.1 server

    @QSRpcService//@QSRpcService(value = "2.0", qps = 1f) 设置版本号及该服务qpspublic class RPCServer implements IRPCServer {    @Override    public String hello(String name) {        return "hello:" + name;    }    @Override    public RPCFuture<String> future(String name) {        return RPCFuture.Ok(name);        //服务端如需异步处理,可创建RPCFuture rpc=new RPCFuture();        //先行返回rpc,后续异步调用rpc.handleResult(t)返回结果    }}

    4.2 client

    @QSRpcReference//@QSRpcReference(version = "2.0",timeout = 10000) 配置版本号及超时IRPCServer rpcServer;//同步调用@ResponseBody@GetMapping("/hello")public String hello() {    return rpcServer.hello("QSPRC");}//异步调用@GetMapping("/future")public String future() {    RPCFuture<String> future = rpcServer.future("QSPRC");    future.setCallback(new Callback<String>() {        @Override         public void handleResult(String result) {            System.out.println("result:" + result);        }       @Override        public void handleError(Throwable error) {            System.err.println("error:" + error);        }    });    return "ok";}

    Future

    • 服务调用支持异步
    • 断路器策略
    • 服务统计治理
    • ...

    Test

    4-core自发自收的情况下2.3万/秒的并发数,实际会更高 Test截图 截图2
    异步调用可达10w+,可拉取test分支测试

    CPUrequesttimeqpsqps(异步)
    i3-8100(4-core/4-thread)10w(8-thread)4331ms2308910w+
    i7-8700(6-core/12-thread)30w(24-thread)6878ms4361720w+

    QSRPC项目技术选型及简介

    1.TCP通信

    1.1 连接模式:

     本项目tcp通信使用长连接+全双工通信(两边可以同时收/发消息),可以保证更大的吞吐量/更少的连接数资源占用,理论上使用一个tcp连接即可满足通信(详见pool),如果使用http/1.1协议的请求-响应模式,同一个连接在同一个时刻只能有一个消息进行传输,如果有大量请求将会阻塞或者需要开更多tcp连接来解决

    1.2 协议:

    TCP长度消息ID协议号加密/压缩内容包尾
    Byte4411(4bit+4bit)n2

     首先,使用长连接那就需要解决tcp粘包问题,常见的两种方式:

    • 包头长度:优点最简单,也是最高效的,缺点是无法感知数据包错误,会导致后续所有包错乱
    • 特定包尾:优点能感知包错误,不影响后续包,缺点需要遍历所有字节,且不能与包内容冲突

     综上,本框架使用的是包头长度+特定包尾,结合了两者优点,避免了缺点,高效实用,检测到包错误会自动断开.没有使用校检码转码等,因为需要考虑实际情况,内网里出错概率非常低,出错了也能重连,对于RPC框架追求性能来说是合适的,即使是外网,后续有需求可以增加校验加密协议
     其次,因为支持全双工那就需要解决消息回调问题,本协议使用了一个消息ID,由客户端生成,服务端返回消息带上;由于发送和接收是非连续的,所以客户端需要维护一个回调池,以ID为key,value为此次请求的context(callback),因为是异步的,请求有可能没有响应,所以池需要有超时机制

    1.3 压缩/加密:

     当出现带宽不足而CPU性能有余时,压缩就派上用场了,用时间换空间。目前支持了snappy/gzip两种压缩,snappy应用于google的rpc上,具有高速压缩速度和合理的压缩率,gzip速度次于snappy,但压缩率较高,根据实际情况配置,前提必须是带宽出现瓶颈/要求,否则不需要开启压缩
     加密功能计划中(加盐位算法)

    1.4 IO框架:

    网络IO目前是基于netty搭建的,支持nio,zero-copy等特性,由于本框架连接模式使用长连接,连接数固定且较少,所以本框架性能对于IO模式(BIO/NIO/AIO)并不是很敏感,netty对于http,iot服务这种有大量连接数的优势就很大了

    2. Tcp pool

     前面说了一个tcp连接即可支撑通信,为啥又用pool了呢,原因有两个:1. netty工作线程对于同一个连接使用同一个线程来处理的,所以如果客户端发送大量请求时,服务端只有一个线程在处理导致性能问题,起初是想服务端再把消息分发到线程池,但后续测试发现此操作在高并发下会导致延迟增大,因为又把消息放回线程池排队了。2. 相对于一条tcp链接,使用pool会更加灵活,且连接数也很少,并没有性能影响; 本框架还基于pool实现了一个[请求-响应]的通信模式*
     客户端Pool的maxIdle(maxActive)=服务节点配置的CPU线程数*2=服务节点netty的工作线程数,pool采用FIFO先行先出的策略,可以保证在高并发下均匀的使用tcp连接,服务端就不用再次分发消息了

    3. 服务注册发现

     分布式系统中都需要一个配置/服务中心,才能进行统一管理.本框架目前使用zookeeper(已支持nacos)进行服务注册,zookeeper是使用类似文件目录的结构,每个目录都可以存一个data
     节点注册是使用[IP:PROT_TIME]作为目录名,data存了节点的json数据,创建模式为EPHEMERAL_SEQUENTIAL(断开后会删除该目录),这样就达到了自动监听节点上下线的效果,加入时间戳是为了解决当节点快速重启时,注册了两个目录,便于进行区分处理
     客户端通过watch目录变化信息,从而获取到所有服务节点信息,同步一个副本到本地Map里(需加上读写锁),客户端就可以实现高效调用对应的服务了,性能瓶颈不用依赖于注册中心,系统可靠性更强,即使注册中心挂了依赖副本也可正常运行

    Log

    v1.1.1(2021-11-25)

    • 支持异步调用,提升框架qps上限
    • 升级依赖
    • 其他优化...

    v1.0.3(2021-04-16)

    • 支持Nacos 2.0
    • 支持yml,自动获取node ip
    • 其他优化...

    v1.0.2(2020-11-26)

    • 客户端支持选择调用指定节点
    • 异常处理优化

    v1.0.1(2020-11-23)

    • Upgrade dependencies

    v0.1.0(2020-11-16)

    • open source

    Other

    • 有问题请Add issues
    • 如果项目对你有帮助的话欢迎star

    鲜花

    握手

    雷人

    路过

    鸡蛋
    该文章已有0人参与评论

    请发表评论

    全部评论

    专题导读
    热门推荐
    阅读排行榜

    扫描微信二维码

    查看手机版网站

    随时了解更新最新资讯

    139-2527-9053

    在线客服(服务时间 9:00~18:00)

    在线QQ客服
    地址:深圳市南山区西丽大学城创智工业园
    电邮:jeky_zhao#qq.com
    移动电话:139-2527-9053

    Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap