TRAS为springcloud提供高性能的RPC能力

TRAS为springcloud提供高性能的RPC能力传统 HTTP 存在的瓶颈 SpringCloud 是一个优秀的开源微服务解决方案 通常采用 HTTP json 的 REST 接口对外提供服务 简洁易用部署方便 很多公司也基于 SpringCloud 作为基础架构去构建自身的微服务架构 但是随着业务规模和用户规模的增长 传统基于的 HTTP 的服务会逐步暴露出一些问题 首先是性能的问题 随着用户请求量的增长和业务逻辑复杂度的提升 我们

传统HTTP存在的瓶颈

Spring Cloud 是一个优秀的开源微服务解决方案,通常采用 HTTP + json 的 REST 接口对外提供服务,简洁易用部署方便,很多公司也基于 Spring Cloud 作为基础架构去构建自身的微服务架构。但是随着业务规模和用户规模的增长,传统基于的 HTTP 的服务会逐步暴露出一些问题。

首先是性能的问题,随着用户请求量的增长和业务逻辑复杂度的提升,我们会发现微服务的单机性能会成为系统瓶颈。

其次是稳定性问题,当一个服务节点A需要依赖于后端的几个服务的时候,我们会发现当其中一个被依赖的服务发生卡顿,很可能会导致前端的服务节点A产生毛刺甚至无法继续提供服务,而且当问题节点没有能够被及时屏蔽或者恢复的时候,还有可能会导致整个系统雪崩。

TARS如何为SpringCloud提供高性能解决方案

TARS 是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架,上述问题在 TARS 框架的发展过程中已经得到了比较好的解决。现在,TARS 通过插件集成到 Spring Cloud 体系中,希望通过输出 TARS 的 RPC 能力针对某些对性能和稳定性要求更高应用的场景提供一种新的解决方案,并且提供了基于 Spring Boot 的开发方式,符合Spring Cloud开发者的使用习惯,可以仅使用较小的开发成本在整个Spring Cloud体系中引入TARS的RPC能力。

将 TARS 结合到 Spring Cloud 中使用,通过 TARS 提供的长连接异步调用和二进制协议可以明显的提升 RPC 调用性能。长连接通过连接复用减少整体的连接数量减少了资源消耗,同时通过二进制协议提升了编解码效率提升了整体的 RPC 性能。

一. 解决SpringCloud传统HTTP网络连接使用率不高的问题 
问题: 
由于HTTP协议本身是无状态的,所以发起一次请求的时候必须等待上一个请求响应才能再次使用这个连接,就算是采用流水线模式一个连接上的请求也会被之前发起的请求所阻塞,如果要提高并发能力则必须要建立大量的连接,而连接的建立、维持和销毁都会消耗系统资源。

二. 解决SpringCloud传统HTTP通讯协议性能低下的问题 
问题: 
HTTP + json 本身是一种可读性很高的文本协议,因此实际传输的数据包会比二进制协议要大不少,而且文本协议在数据的序列化反序列化效率上相比二进制数据的效率要低很多,所以 HTTP 协议本身的性能就不高。

  1. 编解码效率 
    二进制协议的编解码是按二进制位直接进行编解码的,减少了对不确定的字符串解析的过程,直接从对应的二进制位读取数据,效率相比解析文本协议有非常大的提升。
  2. 网络包大小 
    因为所有的数据都是采用二进制存储,数据按位存储减少了对空间的浪费,使得数据序列化后能减少对空间的占用。

TARS协议采用.tars文件定义接口和数据接口,通过提供的工具可以将数据和接口定义翻译成各种语言的代码实现。

接口的共享只需要提供接口的定义文件,使用者通过定义文件直接生成客户端接口代码即可。这样减少了双方的沟通成本,避免了需要写大量的接口定义文档以及解析JSON所需的对象。

三. 解决SpringCloud传统 HTTP服务基于同步线程模型的性能问题 
问题: 
传统的 HTTP 服务多是基于同步的线程模型,由于 HTTP 协议本身无状态,所以在协议层面就不支持异步,所以当我们在客户端发起一次 HTTP 调用时主调线程必须挂起等待被调响应请求,这个时候主调线程的资源则被浪费了,因为线程资源是有限的,大量线程被挂起等待白白浪费了主调方的运算资源。

发起一个异步调用之后,当前线程并不会被阻塞而是继续执行,当收到服务端响应之后在回调线程池中通过回掉函数来执行结果的处理。这样所有的处理线程都一直处于工作的状态中,而不会挂起导致线程资源的浪费。整体上提升了服务的处理能力。

四. 解决SpringCloud服务端基于同步线程模型的稳定性问题 
问题: 
微服务的服务端基于同步的线程模型面临的最大的隐患就是线程的IO等待,比如说一个基于同步的线程模型的微服务,依赖后面的3个接口,微服务本身的线程数是50个,那么当后面依赖的3个接口中有一个延时飚高,只需要有50个对问题接口的调用,就足够把整个微服务的进程挂起,因为当前已经没有线程能够对外提供服务了(当然可以设置超时,但是设置超时治标不治本)。同时,由于微服务线程对问题接口的IO等待,会导致微服务的队列中堆积大量的等待时间过长(可能已经超时)的请求,当问题接口恢复后,服务端会消耗资源去处理大量的过期的请求(请求超时,客户端不再等待)导致问题进一步恶化,严重的甚至会导致系统雪崩。

通过上面TARS的解决方案,看看实际的使用场景

场景一.同步调用,性能提升一倍标题 
通常可以简单可以简单的改造服务,将本来的HTTP接口改为使用TARS,我们对比一下在同步调用场景下TARS调用和HTTP调用的性能差异,这里规定了服务端线程数为100个线程,服务端的处理都为简单的echo服务。我们对比一下在同一台机器上不同RPC方式、不同的客户端线程数以及不同数据包大小的TPS数据: 
这里写图片描述
可以看出,因为采用了连接复用和二进制的协议,整体的调用效率相比使用HTTP有了非常明显的提升,而且是仅仅在简单优化了一下调用方式的情况下,对业务处理逻辑并没有影响。


场景二.异步调用,避免阻塞,提升性能 
假如我们在Spring Cloud中存在这样一个调用关系,A服务需要调用B服务,而B服务需要依赖处理耗时远大于是B服务的C服务。比如在通常的业务场景中,如果API接口需要调用一个订单生成的服务,而订单生成服务只需要生成订单ID计算量相对较小,但是他还需要依赖一个订单写入服务,应为涉及到库存修改、订单写入需要一系列的事务处理,整体耗时远远大于订单ID的生成,所以订单服务大量的线程资源浪费在了等待订单写入服务上。在这种情况下可以使用TARS改造订单服务和写入服务,从而使用异步调用写入服务来提升资源利用率,采用TARS提供的异步RPC能力来进行跟深度的改造: 
这里写图片描述 
通常情况下如果使用同步调用,因为B需要等待C服务的响应,需要花上自身处理耗时的数倍来进行等待C服务返回结果,线程被阻塞浪费线程资源。这样的情况我们可以保持A服务不变,提供REST接口,而B服务采用异步调用来进行改造。如下图所示: 
这里写图片描述 
我们通过简单的代码来模拟上述过程,加入C服务的逻辑时收到请求后Sleep 10s后返回结果,C服务有10个处理线程,最开始B和C之间采用同步调用,要达到最大的并发效率B服务必须也提供10个线程才能够达到最大的并发效率 TPS 为1。此时我们采用异步调用改造B服务: 
这里写图片描述 
此时仅需核数 + 1个线程即可达到最大的处理效率。在通常的业务使用中,如果所有IO均用异步实现,那么只使用核数+1个线程便能达到较高的处理效率,从而避免了同步IO带来的资源浪费。






在以上改造中,对外的HTTP接口并不需要改动,可以仅在内部需要提升RPC性能和用到异步调用的地方进行改造即可,可以平滑的按服务逐步升级。而且因为均采用Spring boot实现,只需要修改接口,其余所有业务代码还是使用Spring注入即可。

写在最后

我们通过插件实现了TARS对Eureka服务发现的支持,提供了Spring boot starter包和相关的注解,能够通过符合Spring Cloud开发者习惯的开发方式快速开发服务。通过对服务发现和开发方式对Spring Cloud集成能够让开发者以较小的代价快速的在整个Spring Cloud的环境中快速引入TARS的RPC能力。

转载自:https://blog.csdn.net/tencent__open/article/details/

原作者:tencent__open

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207018.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午2:38
下一篇 2026年3月19日 下午2:38


相关推荐

  • Thumbnails 处理图片

    Thumbnails 处理图片博客引用处 以下内容在原有博客基础上进行补充或更改 谢谢这些大牛的博客指导 Thumbnails 处理图片 Java 图片处理开源框架 java 使用 google 开源工具实现图片压缩 Thumbnails 原图 amp Amneiltu 原图宽高都小于 3000 不设置 keepAspectRa false 那么只有高会改

    2026年3月17日
    2
  • 浅谈UML的概念和模型之UML九种图

    浅谈UML的概念和模型之UML九种图

    2021年12月4日
    51
  • pycharm中使用GPU跑程序

    pycharm中使用GPU跑程序查看机器上 GPU 情况命令 nvidia smi 功能 显示机器上 gpu 的情况命令 nvidia smi l 功能 定时更新显示机器上 gpu 的情况命令 watch n3nvidia smi 功能 设定刷新时间 秒 显示 GPU 使用情况其中左上侧有 0 1 2 3 的编号

    2026年3月27日
    2
  • ADODB操作数据库函数DBData和qstr

    ADODB操作数据库函数DBData和qstr一代码 php include once adodb5 adodb inc php conn ADONewConnec mysql conn PConnect localhost root root db database14 conn execute setnamesgb23

    2026年3月17日
    2
  • 我为什么放弃Go语言

    我为什么放弃Go语言我为什么放弃Go语言?有好几次,当我想起来的时候,总是会问自己:这个决定是正确的吗?是明智和理性的吗?其实我一直在认真思考这个问题。开门见山地说,我当初放弃Go语言,就是因为两个“不爽”:第一,对Go语言本身不爽;第二,对Go语言社区里的某些人不爽。毫无疑问,这是非常主观的结论,但是我有足够详实的客观的论据。

    2022年6月30日
    26
  • Window系统内核版本号及其查看方法「建议收藏」

    Window系统内核版本号及其查看方法「建议收藏」一.WindowsNTWindwosNT是一系列操作系统的总称。WindowsNT(NewTechnology)是Microsoft在1993年推出的面向工作站、网络服务器和大型计算机的网络操作系统,也可做PC操作系统。它与通信服务紧密集成,基于OS/2NT基础编制。OS/2由微软和IBM联合研制,分为微软的MicrosoftOS/2NT与IBM的IBMOS/2。

    2022年8月23日
    16

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号