这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记
课程资料
课程PPT:深入浅出 RPC 框架.pptx - 飞书云文档 (feishu.cn)
什么是RPC框架
随着公司规模扩大和业务量增加,单体应用逐步变为服务/微服务的架构模式,服务之间的调用大多采用RPC的方式调用,或者消息队列的方式进行解耦。几乎每个大厂都会创建自己的RPC框架,或者基于知名的RPC框架进行改造。
- RPC(Remote Procedure Calls)
- RPC需要解决的问题 1.函数映射 2.数据转换为字节流 3.网络传输
- RPC概念模型
RPC原理
RPC调用流程
要让网络通信细节对使用者透明,我们需要对通信细节进行封装,我们先看下一个RPC调用的流程涉及到哪些通信细节:
- 服务消费方(client)调用以本地调用方式调用服务;
- client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
- client stub找到服务地址,并将消息发送到服务端;
- server stub收到消息后进行解码;
- server stub根据解码结果调用本地的服务;
- 本地服务执行并将结果返回给server stub;
- server stub将返回结果打包成消息并发送至消费方;
- client stub接收到消息,并进行解码;
- 服务消费方得到最终结果。
RPC的好处
- 单一的职责
- 可扩展性强,资源使用率优
- 故障隔离,服务的整体可靠性更高
影响RPC框架性能的因素
在物理服务器性能相同的情况下,以下几个因素会对一款RPC框架的性能产生直接影响: 使用的网络IO模型:RPC服务器可以只支持传统的阻塞式同步IO,也可以做一些改进让RPC服务器支持非阻塞式同步IO,或者在服务器上实现对多路IO模型的支持。这样的RPC服务器的性能在高并发状态下,会有很大的差别。特别是单位处理性能下对内存、CPU资源的使用率。
基于的网络协议:一般来说您可以选择让您的RPC使用应用层协议,例如HTTP或者HTTP/2协议,或者使用TCP协议,让您的RPC框架工作在传输层。工作在哪一层网络上会对RPC框架的工作性能产生一定的影响,但是对RPC最终的性能影响并不大。但是至少从各种主流的RPC实现来看,没有采用UDP协议做为主要的传输协议的。
消息封装格式:选择或者定义一种消息格式的封装,要考虑的问题包括:消息的易读性、描述单位内容时的消息体大小、编码难度、解码难度、解决半包/粘包问题的难易度。当然如果您只是想定义一种RPC专用的消息格式,那么消息的易读性可能不是最需要考虑的。消息封装格式的设计是目前各种RPC框架性能差异的最重要原因,这就是为什么几乎所有主流的RPC框架都会设计私有的消息封装格式的原因。dubbo中消息体数据包含dubbo版本号、接口名称、接口版本、方法名称、参数类型列表、参数、附加信息
Schema 和序列化(Schema & Data Serialization):序列化和反序列化,是对象到二进制数据的转换,程序是可以理解对象的,对象一般含有 schema 或者结构,基于这些语义来做特定的业务逻辑处理。考察一个序列化框架一般会关注以下几点:
Encoding format 。是 human readable(是否能直观看懂 json) 还是 binary(二进制)。
Schema declaration 。也叫作契约声明,基于 IDL,比如 Protocol Buffers/Thrift,还是自描述的,比如 JSON、XML。另外还需要看是否是强类型的。
语言平台的中立性 。比如 Java 的 Native Serialization 就只能自己玩,而 Protocol Buffers 可以跨各种语言和平台。
新老契约的兼容性 。比如 IDL 加了一个字段,老数据是否还可以反序列化成功。
和压缩算法的契合度 。跑 benchmark (基准)和实际应用都会结合各种压缩算法,例如 gzip、snappy。
性能 。这是最重要的,序列化、反序列化的时间,序列化后数据的字节大小是考察重点。
序列化方式非常多,常见的有 Protocol Buffers, Avro,Thrift,XML,JSON,MessagePack,Kyro,Hessian,Protostuff,Java Native Serialize,FST 。
实现的服务处理管理方式:在高并发请求下,如何管理注册的服务也是一个性能影响点。您可以让RPC的Selector/Processor使用单个线程运行服务的具体实现(这意味着上一个客户端的请求没有处理完,下一个客户端的请求就需要等待)、您也可以为每一个RPC具体服务的实现开启一个独立的线程运行(可以一次处理多个请求,但是操作系统对于“可运行的最大线程数”是有限制的)、您也可以线程池来运行RPC具体的服务实现(目前看来,在单个服务节点的情况下,这种方式是比较好的)、您还可以通过注册代理的方式让多个服务节点来运行具体的RPC服务实现。
常用的RPC框架
- Thrift:thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。
- gRPC:一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。
- Dubbo:Dubbo是一个分布式服务框架,以及SOA治理方案。其功能主要包括:高性能NIO通讯及多协议集成,服务动态寻址与路由,软负载均衡与容错,依赖分析与降级等。Dubbo是阿里巴巴内部的SOA服务化治理方案的核心框架,Dubbo自2011年开源后,已被许多非阿里系公司使用。
- Spring Cloud:Spring Cloud由众多子项目组成,如Spring Cloud Config、Spring Cloud Netflix、Spring Cloud Consul 等,提供了搭建分布式系统及微服务常用的工具,如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性token、全局锁、选主、分布式会话和集群状态等,满足了构建微服务所需的所有解决方案。Spring Cloud基于Spring Boot, 使得开发部署极其简单。
如何选择RPC框架
选择一个rpc框架会基于多方面的考虑: 框架特性、性能、成熟度、技术支持、社区活跃度等多个方面。最重要一点,这也是往往很多技术人员进入的误区,“对于技术,不要为了使用而使用,用最简单合适的技术实现解决问题才是正道”。架构是服务于业务的,能快速方便的满足业务需求的架构才是好的架构。没有最好的,只有适合自己的。
文章引用
原文链接1:blog.csdn.net/m0_62222133… 原文链接2:blog.csdn.net/qwer1234512…