网站开发各个文件,网站建设原创,固安县城乡和住房建设局网站,wordpress新建阅读量字段一、What
1#xff09;小故事 张三和李四都在同一个家公司负责商品交易的模块#xff0c;两个人平时开发甚是紧密。 #x1f64b;#x1f3fb;♂️ 张三#xff1a;“李四#xff0c;我这边一个商品下单了#xff0c;但是付款数额不对#xff0c;你帮我查下支付有没…一、What
1小故事 张三和李四都在同一个家公司负责商品交易的模块两个人平时开发甚是紧密。 ♂️ 张三“李四我这边一个商品下单了但是付款数额不对你帮我查下支付有没有问题” 李四“张三支付这边检验价格的时候有点问题实付金额和预付金额对不上” 往常他们相邻而坐有什么问题也是 张口就问 。但是随着业务的增长他们的工作被细化到不同的子模块中而 分布式系统 的概念也恰逢其时地变得流行起来。拆分系统的计划迫在眉睫。于是张三自然而然地分配到了订单模块而李四到了交易模块。相应两个人的工位也需要分开这个时候他们意识到应该没法像从前那样即呼即应了 。 这个时候该如何解决沟通的问题 李四人搬走了但是 联系方式 还在张三需要李四协助的时候可以通过 电话 的方式直呼李四虽然说通过电话的这种方式略显间接但仍然保留了解问题的能力只是沟通的形式变了。 通过阅读这个故事我们总结一下其中几个核心概念
张三李四可以直接交谈。直接调用拆分模块分布式系统联系方式接口定位利用电话沟通远程通信打电话的过程过程调用 而这几个概念也正是 RPC 的核心所在。
2概要 RPC (Remote Procedure Call) 是一种用于实现远程通信和分布式计算的协议。它允许在不同的计算机或进程之间进行通信使得这些计算机或进程能够像调用本地函数一样调用位于远程计算机或进程上的函数或方法。 RPC 协议的基本原理是客户端调用远程服务器上的函数并将函数参数传递给服务器。 服务器执行相应的函数逻辑并将结果返回给客户端。 从客户端的角度来看RPC 调用就像是调用本地函数一样而不需要关心远程函数的实现和通信细节。 简单来说从本质上讲它使一台机器上的程序能够调用另一台机器上的子程序而不会意识到它是远程的。
3HTTP
1、HTPP 与 RPC 的先后
RPC是一个较早的抽象它的思想在1970年代早期就已经存在而具体实现上的一个里程碑是在1980年代。它代表了一种通用概念从一个计算机进程中调用另一个进程的函数或过程无论这两个进程是否在同一台机器上。 HTTP首次出现在1991年。它是由蒂姆·伯纳斯-李在1990年至1991年期间开发的作为万维网World Wide Web简称WWW项目的一部分。 因此从时间线上看RPC 是早于 HTTP 出现的。
2、既生 RPC 何生 HTTP
有了RPC理论上可以通过各种协议进行方法调用但HTTP为万维网提供了一个标准化的、广泛支持的方式来交换信息和服务它不仅限于方法调用还包括数据的获取、提交、更新和删除等。 比方说 A 公司开发了一套数据管理系统在 A 公司内部可以使用 RPC 协议 进行方法调用获取数据而这个时候 B 公司想要集成 A 公司的能力这个时候通过方法调用的方式就不大合适就需要利用万维网上更加标准的协议来进行通信也就是 HTTP 协议。 主要区别
RPC 与 REST 最大的区别就在于 RPC 提供了更好的抽象甚至将网络传输细节彻底隐藏了而 REST 没有。具体来说REST 至少要求用于提供 URL 以及请求参数而 RPC 隐藏了与网络传输的相关实现细节。另一方面RPC 可以基于任何网络通信协议而 REST 通常基于 HTTP或者 HTTPS协议。
设计目标 RPC 协议是一种用于实现远程过程调用的协议它主要是让客户端能够像调用本地函数一样调用远程服务器上的函数。更侧重于方法的调用和参数传递通常用于构建分布式系统、微服务架构等场景提供了更直接的远程函数调用能力。HTTP 协议是一种通用的应用层协议。它提供了一套标准的请求和响应语义支持网页浏览、资源访问、API 调用等场景。HTTP 具有广泛的应用范围可以用于浏览器与服务器之间的通信也可以用于不同系统之间的数据交换。 传输协议 RPC 协议可以基于多种传输协议实现如 TCP、UDP、HTTP 等通过自定义的协议栈和编码方式来进行数据传输。HTTP 协议基于 TCP/IP使用统一的格式规范如请求行、请求头、请求体等以及常见的编码方式如 JSON、XML、Form 表单等。 通信模型 RPC 协议是一种点对点的通信模型客户端和服务器之间建立直接的连接进行函数调用和返回结果。HTTP 协议是一种客户端-服务器模型客户端发送请求服务器接收请求并返回响应每次请求都需要建立新的连接。
3、性能比较
HTTP 协议和 RPC 协议在性能方面有一些差异这些差异主要由以下几个因素决定
通信开销 HTTP 协议通常使用文本格式如 JSON、XML进行数据传输相对较为冗长。每次请求和响应都会包含大量的头部信息增加了数据传输的开销。RPC 协议通常使用二进制序列化格式如 Protocol Buffers、Thrift相对更为紧凑。它通常专注于方法调用和参数传递减少了不必要的开销。 连接复用 HTTP 协议在默认情况下使用短连接即每个请求都需要建立一个新的连接。这对于频繁的请求会增加连接建立和关闭的开销。RPC 协议通常支持长连接在一个连接上可以进行多次的方法调用。这样可以减少连接的建立和关闭次数提高性能。 序列化和反序列化 HTTP 协议使用通用的文本格式进行数据传输需要进行文本到对象的序列化和反序列化操作。这些操作可能会消耗一定的时间和计算资源。RPC 协议通常使用二进制序列化格式可以更高效地进行序列化和反序列化减少了转换的开销。
相对来说RPC 协议通常在性能方面比 HTTP 协议更优秀。由于 RPC 协议的设计目标更加专注于方法调用和参数传递它通常采用更紧凑的数据格式、支持长连接等机制以提供更高的性能和效率。但在实际应用中具体的性能差异需要根据具体情况进行评估和测试。
二、How
1核心概念
客户端Client 发起远程函数调用的一方。负责将本地的函数或方法调用转化为网络请求并将网络响应转化回本地的函数或方法调用的结果。客户端存根Client Stub 客户端存根将函数调用及其参数编码、序列化后通过网络发送请求。网络模块Network 用于传输远程调用讯息的媒介可以是TCP/IP、HTTP或其他网络协议。服务端骨架Server Skeleton 与客户端存根对应负责将接收到的请求解包、反序列化后调用实际的服务服务过程。并将结果重新包装发送回客户端。服务端Server 提供远程过程实际执行的地方即实现了具体逻辑的服务或应用程序。
2通信流程
从上面中我们认识了 RPC 的五大概念可以通过一张时序图将五大概念串行起来如下 具体流程
Client 客户端 通过调用本地服务的方式调用需要消费的服务Client Stub 存根 接收到调用请求后负责将方法入参等信息序列化(组装)成能够进行网络传输的消息体Client Stub 存根 找到远程的服务地址并且将消息通过网络发送给服务端Server Stub 服务端骨架 收到消息后进行解码(反序列化操作)Server Stub 服务端骨架 根据解码结果调用本地的服务进行相关处理Server 服务端 执行具体业务逻辑并将处理结果返回给 Server Stub 服务端骨架Server Stub 服务端骨架 将返回结果重新打包成消息(序列化)并通过网络发送至消费方Client Stub 存根 接收到消息并进行解码(反序列化);Client Stub 存根 将解码后的结果返回给 Client 客户端
3实现架构
当我们认识到 RPC 的通信架构了进一步就可以考虑如何实现 RPC 框架了
其中 Client 客户端 和 Server 服务端 是关键角色一个负责消费一个负责提供。在 Client 客户端 我们要实现无感知地侵入达到客户端完全不会意识到 Server 服务端 的存在就需要用上 Proxy 代理 能力。当代理拦截到客户端调用的方法后还需要将数据序列化后进行发送这个时候 Serializer 模块 就不可少当序列完数据就得通过网络将数据进行传输因此便需要 Network 模块但是在传输之前我们需要找到远程服务的地址因此 Registry 注册中心 也少不了。
1、五大模块
通过简单梳理我们大概整理了 5 大模块
客户端Client 客户端模块发起远程函数调用请求。序列化模块Serializer 序列化模块负责数据的序列化和反序列化。网络Network 网络模块用于传输远程调用信息。注册中心Registry 注册中心模块负责服务的注册与发现。服务端Server 提供远程过程实际执行的地方即实现了具体逻辑的服务或应用程序。
架构图如下
2、技术分析
聊完理论谈实践为了实现以上各个模块之间的串行能力我们需要用到的技术能力如下
1动态代理
生成 Client Stub 存根 和 Server Stub 服务端骨架 的时候需要用到 Java 的动态代理技术可以使用JDK提供的原生的动态代理机制也可以使用开源的CGLib代理 Javassist字节码生成技术。
在构建RPC框架时生成 Client Stub 存根 和 Server Stub 服务端骨架 是实现远程方法调用不可或缺的一环。这一过程往往需要动态代理技术来实现在Java平台上我们有几种选择来达到这个目的。
使用JDK提供的原生的动态代理机制它主要是通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来完成的适用于需要代理接口而非类的场合。使用开源的CGLib库。CGLib能够在运行时对类进行扩展通过继承的方式生成新的子类它不需要接口就能实现动态代理。Javassist 提供了一种更加直接操作字节码的方式通过这种字节码技术可以在不打破原有类结构的情况下新增或者改变类的行为。
2序列化
序列化是数据处理的关键环节它使得复杂数据结构能够转换成字节序列以便于存储或网络传输这一过程亦称作编码。相对地反序列化将这些字节序列重新构建成原始对象即解码过程。在分布式系统与数据交换频繁的应用中序列化的效率至关重要。
当评估并选择合适的序列化框架时效率、灵活性和生态支持是几个关键的考量因素。当前市场上的一些高效开源序列化库比如Kryo、FastJson和Protobuf各自都有其优势。
Kryo 是一个小巧且快速的序列化库它被广泛应用于需要高速序列化操作的场景尤其是在游戏和高性能计算中。FastJson 以其速度快和使用简单闻名特别适用于Web服务和轻量级应用它的优势在于处理JSON格式数据的高效性。Protobuf由Google开发是一个以效率和兼容性为主要目标的结构化数据序列化方法。相较于传统的XML它更小、更快、更简单且拥有良好的跨平台性。
3网络通信
为了提高系统处理并发请求的能力传统的同步阻塞IOBIO模型并不适宜因为它在等待数据读写过程中会导致线程阻塞从而降低了并发处理的效率。因此采用非阻塞IONIO是解决高并发场景下性能问题的恰当选择。NIO支持异步IO操作允许线程在处理其它任务时并行地等待IO操作完成这大大提升了资源的利用率和系统的吞吐量。
在构建高并发网络应用时我们有多种框架可以选择。Netty和Apache MINA是两个流行的高性能网络应用框架它们都利用了Java NIO的优势。Netty特别被广泛用于其简单的API和稳定的性能而MINA同样提供了一个易于使用和扩展的异步IO框架。根据应用的具体需求和开发团队的熟悉度我们可以选取最适合的框架来构建我们的网络服务以确保在高并发场景下应用的最佳网络性能和响应速度。
4注册中心
服务注册与发现是核心组件它用于服务间的动态定位。市面上有多种成熟的服务注册中心方案包括Redis、ZooKeeper、Consul等。其中
选择合适的注册中心时我们不仅需要考虑技术特性比如数据一致性、可用性和可扩展性还要考虑与现有系统环境的兼容性以及未来的维护和支持情况。每种方案都有其特定优势和场景适用性例如Redis在处理高速缓存和消息队列方面表现卓越Consul提供更现代的服务网络功能如健康检查和服务网格集成ZooKeeper凭借其强一致性的特点经常被选用来处理服务注册和发现的问题同时有效解决分布式系统中避免单点故障及处理分布式部署的挑战
4常见 RPC 框架
1、gRPC
开源RPC框架由Google主导开发。使用HTTP/2作为传输协议以Protocol Buffers作为其接口定义语言。支持多种编程语言适用于构建跨语言的服务。
2、Apache Thrift
由Facebook开发并贡献给Apache的RPC框架。支持多种编程语言允许定义数据类型和服务接口在一个统一的接口描述语言(IDL)文件中。框架生成服务端和客户端代码供不同语言编写的程序使用。
3、Apache Dubbo
高性能的Java RPC框架。用于构建大规模分布式系统支持多种通信协议。提供灵活的服务治理和动态配置功能。
三、End
在本篇文章中我们探究了 RPC 的核心概念和基本原理了解到其如何使得跨网络的服务调用变得透明而无缝。了解RPC不仅仅是关于掌握一个技术的使用更是理解分布式系统设计中关于模块化、服务解耦、和伸缩性设计的深层次思想。 随着微服务架构的兴起RPC也随之进化适应了更复杂的网络模式和更严格的性能需求。无论你是一个初级开发者还是高级开发者RPC都应该是你日常开发过程中绕不开的一个话题。未来的网络计算充满了无限可能而RPC无疑将继续在其中扮演着重要的角色。感谢您的阅读