当前位置: 首页 > news >正文

RPC通讯基础原理

1.RPC(Remote Procedure Call)概述

        RPC是一种通过网络从远程计算机上调用程序的技术,使得构建分布式计算更加容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性,提供一种透明调用机制,让使用者不必显式的区分本地调用和远程调用;

1.1 RPC优点

  • RPC框架一般使用长连接,不必每次通信都三次握手,减少网络开销;
  • RPC框架一般都有注册中心,有丰富的监控管理、发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作,协议私密安全性较高;
  • RPC协议简单内容小效率高,服务化架构、服务化治理;
  • RPC可以基于TCP实现(Dubbo、Thrift)也可以基于HTTP2(gRPC)

1.2 RPC框架

  • Dubbo:阿里巴巴开发的开源RPC框架,支持Java语言 ;
  • Thrift:FaceBook开发的跨语言RPC框架,支持多种语言;
  • gRPC:Google开发的跨语言RPC框架,支持多种语言;
  • SpringCloud:Pivotal开发的RPC框架,提供了丰富的生态组件

1.3 RPC调用流程

所涉及的技术:

  1. 动态代理:生成Client Stub(客户端存根)和Server Stub(服务端存根)的时候需要用到java动态代理技术。
  2. 序列化:在网络中,所有的数据都将会被转化为字节进行传送,需要对这些参数进行序列化和反序列化操作;目前主流高效的开源序列化框架有Kryo、fastjson、Hessian、Protobuf等。
  3. NIO通信:Java 提供了 NIO 的解决方案,Java 7 也提供了更优秀的 NIO.2 支持。可以采用Netty或者mina框架来解决NIO数据传输的问题。开源的RPC框架Dubbo就是采用NIO通信,集成支持netty、mina、grizzly。
  4. 服务注册中心:通过注册中心,让客户端连接调用服务端所发布的服务。主流的注册中心组件:Redis、Nacos、Zookeeper、Consul 、Etcd。Dubbo采用的是ZooKeeper提供服务注册与发现功能。
  5. 负载均衡:在高并发的场景下,需要多个节点或集群来提升整体吞吐能力。
  6. 健康检查:健康检查包括,客户端心跳和服务端主动探测两种方式。 

2.序列化技术

        网络传输中,数据必须采用二进制形式,序列化技术就负责对数据进行序列化(对象转成二进制数据)和反序列化(二进制数据转回对象);

2.1 常用的序列化技术

2.1.1 JDK原生序列化

public static void main(String[] args) throws IOException,ClassNotFoundException {String basePath = "D:/TestCode";FileOutputStream fos = new FileOutputStream(basePath +"tradeUser.clazz");TradeUser tradeUser = new TradeUser();tradeUser.setName("Mirson");ObjectOutputStream oos = new ObjectOutputStream(fos);oos.writeObject(tradeUser);oos.flush();oos.close();FileInputStream fis = new FileInputStream(basePath +"tradeUser.clazz");ObjectInputStream ois = new ObjectInputStream(fis);TradeUser deStudent = (TradeUser) ois.readObject();ois.close();System.out.println(deStudent);
}
  • 首先序列化的对象必须实现java.io.Serializable接口;
  • 通过ObjectOutputStream和ObjectInputStream的读和写来对对象进行序列化和反序列化;
  • 对象的序列化id须一致才能反序列化(private static final long serialVersionUID);
  • 序列化不会保存静态变量,变量前加Transient关键字可以不序列化该变量

2.1.2 JSON序列化

        如常用的fastjson

        JSON序列化具有较好的扩展性、可读性和通用性,但占用空间多、效率低;

2.1.3 Hessian2序列化

        Hessian 是一个动态类型,二进制序列化,并且支持跨语言特性的序列化框架。
        Hessian 性能上要比 JDK、JSON 序列化高效很多,并且生成的字节数也更小。有非常好的兼容性和稳定性,所以 Hessian 更加适合作为 RPC 框架远程通信的序列化协议。

TradeUser tradeUser = new TradeUser();
tradeUser.setName("Mirson");
//tradeUser对象序列化处理
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Hessian2Output output = new Hessian2Output(bos);
output.writeObject(tradeUser);
output.flushBuffer();
byte[] data = bos.toByteArray();
bos.close();
//tradeUser对象反序列化处理
ByteArrayInputStream bis = new ByteArrayInputStream(data);
Hessian2Input input = new Hessian2Input(bis);
TradeUser deTradeUser = (TradeUser) input.readObject();
input.close();
  • 不支持Linked对象,如LInkedHashMap、LinkeHashSet等,但可以通过CollectionSerializer类修复
  • 不支持Locale类,可以通过扩展ContextSerializerFactory类修复
  • Byte/Short在反序列化的时候会转成Integer

2.1.4 Protobuf序列化

        google推出的开源序列库,序列化后的体积小、序列化速度快;

3.动态代理

        通过运行时动态创建代理对象,进行额外处理(如增强功能、日志记录、事务管理、权限控制等),再将调用传递给实际的目标对象;

3.1 常用的动态代理技术

3.1.1 JDK动态代理

        JDK动态代理为Java标准库的一部分,不需要引入外部依赖;

public class JdkProxyTest {/*** 定义用户的接口*/public interface User {String job();}/*** 实际的调用对象*/public static class Teacher {public String invoke(){return "i'm Teacher";}}/*** 创建JDK动态代理类*/public static class JDKProxy implements InvocationHandler {private Object target;JDKProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[]paramValues) {return ((Teacher)target).invoke();}}public static void main(String[] args){// 构建代理器JDKProxy proxy = new JDKProxy(new Teacher());ClassLoader classLoader = ClassLoaderUtils.getClassLoader();// 生成代理类User user = (User) Proxy.newProxyInstance(classLoader, newClass[]{User.class}, proxy);// 接口调用System.out.println(user.job());}
}

3.1.2 Cglib动态代理

        Cglib是一个强大的、高性能代码生成包,广泛被许多AOP框架使用,支持方法级别的拦截。

3.1.3 Javassist动态代理

        一个开源的分析、编辑和创建Java字节码的类库。javassist是jboss的一个子项目,它直接使用java编码的形式,不需要了解虚拟机指令,可以动态改变类的结构,或者动态生成类。Javassist 的定位是能够操纵底层字节码,所以使用起来并不简单,Dubbo 框架的设计者为了追求性能花费了不少精力去适配javassist。

3.1.4 Byte Buddy 字节码增强库

        Byte Buddy是致力于解决字节码操作和 简化操作复杂性的开源框架。Byte Buddy 目标是将显式的字节码操作隐藏在一个类型安全的领域特定语言背后。它属于后起之秀,在很多优秀的项目中,像Spring、Jackson 都用到了 Byte Buddy 来完成底层代理。相比 Javassist,Byte Buddy 提供了更容易操作的 API,编写的代码可读性更高。

3.2 不同动态代理技术对比

        Byte Buddy > CGLIB > Javassist> JDK

  • 数据来自 Blog | JRebel & XRebel by Perforce

4.服务注册发现

        在服务较多的项目中使得客户端能够及时感知服务端的变化,及时获取服务节点的连接信息;

        目前用的比较多的就是Nacos和ZooKeeper;

5.网络IO模型

        包括同步阻塞IO(BIO)、同步非阻塞IO(NIO)、IO多路复用、信号驱动IO、异步非阻塞IO(AIO)

        阻塞:请求了之后线程一直等待回复;

        非阻塞:请求之后立刻相应,线程可以干别的,并且轮询read是否完成;

5.1 IO多路复用

        IO多路复用(I/O Multiplexing)是一种允许单个线程管理多个输入输出(I/O)操作的技术。它通过将多个 I/O 操作注册到一个选择器(Selector)上,然后阻塞等待其中任何一个 I/O 操作就绪,从而实现高效的 I/O 管理。IO多路复用在高并发服务器中非常有用,因为它可以显著减少系统资源的消耗,提高系统的吞吐量。

        使用select进行IO请求与同步阻塞模式类似,甚至单条速度由于添加了监视socket效率更低,但是用户可以在一个线程内同事处理多个socket的IO请求,实现类似多线程的同步阻塞;

5.1.1 IO多路复用的实现方式

selectpollepoll(仅Linux)
操作方式遍历遍历回调
底层实现bitmap数组红黑树
IO效率每次调用都线性遍历,O(n)时间复杂度每次调用都线性遍历,O(n)时间复杂度每当fd就绪,系统注册的回调函数就会被调用,将就绪fd放到readyList里面,O(1)时间复杂度
最大连接数1024(x86)或2048(x64)无上限无上限
fd拷贝每次调用select,都需要把fd集合从用户态拷贝到内核态每次调用poll,都需要把fd集合从用户态拷贝到内核态调用epoll_ctl时拷贝进内核并保存,之后每次epoll_wait不拷贝

5.1.2 IO多路复用与阻塞IO对比

        IO多路复用更适合高并发的场景,可以用较少的线程处理较多的socket的IO请求;阻塞IO每处理一个socket的IO请求都会阻塞线程,适合并发量低的场景,不需要发起大量select调用,这种场景下阻塞IO开销比IO多路复用低;

        RPC调用大多情况下是高并发的场景,所以RPC框架一般会选择IO多路复用的方式,而且在linux环境下要使用epoll方式;

5.2 零拷贝

        系统内核处理IO操作包含两个阶段:等待数据、拷贝数据

  • 等待数据:系统内核在等待网卡接收到数据后,把数据写到内核中;
  • 拷贝数据:系统内核在获取到数据后,将数据拷贝到用户进程的空间中;

        进程的每一次写操作 都会把数据写到用户空间的缓冲区内,再由CPU将数据拷贝到系统内核的缓冲区,之后再由DMA将数据拷贝到网卡中,最后由网卡发送出去;

        零拷贝指的就是取消用户空间与内核空间之间的数据拷贝操作;

        Netty中的零拷贝,与此处的操作系统的零拷贝有一定区别,Netty的零拷贝实际上是对用户空间中数据操作的优化,Netty的接收和发送ByteBuffer采用DIRECTBUFFERS,使用堆外的直接内存(内存对象分配在JVM中堆以外的内存)进行Socket读写,不需要进行字节缓冲区的二次拷贝;

相关文章:

RPC通讯基础原理

1.RPC(Remote Procedure Call)概述 RPC是一种通过网络从远程计算机上调用程序的技术,使得构建分布式计算更加容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性,提供一种透明调用机制,让使用者不…...

JavaScript 第18章:安全性

在JavaScript开发中,确保应用的安全性是非常重要的。下面我将根据你提到的几个方面来讲解如何增强Web应用程序的安全性。 XSS(跨站脚本)攻击防御 示例代码: function escapeHTML(unsafe) {return unsafe.replace(/&/g, &qu…...

基于workbox实现PWA预缓存能力

引言 Service Worker 是一项流行的技术,尽管在许多项目中尚未得到充分利用。基于本次项目首页加载优化的机会,决定尝试使用 Google 出品的 Workbox,以观察其优化效果。 开始 安装 项目使用 Webpack 打包,而 Workbox 提供了 We…...

探索Web3生态系统:社区、协议与参与者的角色

Web3代表着互联网的下一个演变阶段,旨在通过去中心化技术赋予用户更大的控制权和参与感。在这个新兴生态系统中,社区、协议和参与者扮演着不可或缺的角色,共同推动着Web3的建设与发展。 社区的核心作用 在Web3中,社区通过提供反馈…...

无人机电机故障率骤降:创新设计与六西格玛方法论双赢

项目背景 TBR-100是消费级无人机头部企业推出的主打消费级无人机,凭借其出色的续航能力和卓越的操控性,在市场上获得了广泛认可。在产品运行过程,用户反馈电机故障率偏高,尤其是在飞行一段时间后出现电机过热、损坏以及运行不稳定…...

samba禁用时拷贝服务器文件到本地的脚本

Android系统开发一般在ubuntu服务器上,我们办公电脑一般是windows。在将编译出来的模块push到板子上时,一般采用adb push 方式。 有时由于种种原因会出现服务器禁用了samba,导致无法直接用adb push 的情况。 下面介绍用winscp 走ssh 拷贝服…...

C#代码 串口通信晋中A2板,控制直流电机

1,在电脑中给晋中板中下载编译好的程序。 0x39 :开启电机的标识 代码: /********************************************************************************** **** 实验名称:串口通信实验 接线说明: 实验现象&…...

3 机器学习之假设空间

归纳(induction)与演绎(deduction)是科学推理的两大基本手段。前者是从特殊到一般的“泛化”(generalization)过程,即从具体的事实归结出一般性规律;后者则是从一般到特殊的“特化”(specialization)过程,即从基础原理推演出具体状况。例如&a…...

基于STM32的风速风向传感器设计

引言 本项目设计了一个基于STM32的风速和风向传感器系统,能够通过组合使用旋转式风速传感器和电子罗盘,实时测量风速和风向,并将数据通过显示屏或无线模块发送给用户。该系统适用于气象监测、环境监控、农业自动化等场景,具有准确…...

域名申请.

操作场景 Internet上有成千上万台主机,每一台主机都对应一个唯一的IP地址。IP地址因不具备实际意义,非常难于记忆,于是就产生了域名。 域名(Domain Name)是一串用点分隔的字符串组成的名称(例如huaweiclo…...

mysql5.7与mysql8.0身份认证插件的区别

MySQL 5.7 和 MySQL 8.0 在身份认证插件方面有一些重要的区别。这些变化主要集中在默认的身份验证插件、密码管理和安全性增强上。 默认身份验证插件 MySQL 5.7 默认插件: mysql_native_password mysql_native_password 是 MySQL 5.7 及更早版本中的默认身份验证插件。它使用…...

进化吧!原始人

如果你想体验一下人类的进化过程~ 如果你有一颗充满探索的好奇心~ 千万不要错过博主新开发的小游戏哦! 点击链接,立即体验! 🙋 欢迎来到冒险互动游戏《进化吧原始人》! 🦍 在这里,你将扮演一…...

SaaS架构:中央库存系统架构设计

大家好,我是汤师爷~ 近年来,越来越多的零售企业大力发展全渠道业务。在销售额增长上,通过线上的小程序、直播、平台渠道等方式,拓展流量变现渠道。在会员增长方面,通过多样的互动方式,全渠道触达消费者&am…...

C语言中点操作符(.)和箭头操作符(->)的区别

在C语言中,点操作符(.)和箭头操作符(->)用于访问结构体的成员,但它们的使用方式有所不同。以下是具体介绍: 点操作符(.)的使用 直接访问结构体变量的成员&#xff1a…...

基于FPGA的以太网设计(一)

以太网简介 以太网(Ethernet)是一种计算机局域网技术。IEEE组织的IEEE 802.3标准制定了以太网的技术标准,它规定了包括物理层的连线、电子信号和介质访问控制的内容。以太网是目前应用最普遍的局域网技术,取代了其他局域网标准如…...

Insert into on duplicate key update 死锁问题解析

Insert into on duplicate key update 死锁问题解析 背景 前段时间的需求中有这个么一个场景,每天早上需要通过定时任务到不同的平台拉取一些广告投放的相关数据,涉及的表比较多,数据量也比较大,有的需要全量同步,有…...

Apache Lucene 10 已发布!Lucene 硬件效率改进及其他改进

作者:来自 Elastic Adrien Grand Apache Lucene 10 刚刚发布,重点关注硬件效率!查看主要版本亮点。 Apache Lucene 10 终于发布了!自 Lucene 9.0(于 2021 年 12 月发布,距今已有近 3 年)以来&a…...

【SQL】SQL查询语句

目录 🎄 基本查询语法 ⭐查询多个字段 ⭐设置别名 ⭐去除重复记录 ⭐ 数据准备 ⭐ 案例 🎄 条件查询 ⭐ 语法 ⭐ 案例 🎄 聚合函数 ⭐ 介绍 ⭐ 常见的聚合函数 ⭐ 语法 ⭐ 案例 🎄 分组查询 ⭐ 语法 ⭐ where与having的区…...

AGI 之 【Dify】 之 使用 Docker 在 Windows 端本地部署 Dify 大语言模型(LLM)应用开发平台

AGI 之 【Dify】 之 使用 Docker 在 Windows 端本地部署 Dify 大语言模型(LLM)应用开发平台 目录 AGI 之 【Dify】 之 使用 Docker 在 Windows 端本地部署 Dify 大语言模型(LLM)应用开发平台 一、简单介绍 二、Docker 下载安…...

机器学习摘下诺奖桂冠

前言 近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家,如今却将全球范围内对机器学习和神经网络的研究和开发作为了一…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)&#xff0…...

今日科技热点速览

🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性&#xf…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

文件上传漏洞防御全攻略

要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...