【最新Dubbo3深入理解】Dubbo3核心Tripple协议详解

2024-02-22 16:20

本文主要是介绍【最新Dubbo3深入理解】Dubbo3核心Tripple协议详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!

在我后台回复 「资料」 可领取编程高频电子书
在我后台回复「面试」可领取硬核面试笔记

文章导读地址:点击查看文章导读!

感谢你的关注!

最新 Dubbo3 深入理解原理系列

在这里插入图片描述

Tripple 协议

因此 Dubbo 框架为了提升协议的通用性,可以和 SpringCloud 以及其他语言应用进行通信,在 Dubbo3.x 版本推出了基于 HTTP/2 的 Triple 协议,也就是说 Tripple 协议在发送数据时会根据 HTTP/2 协议的格式来发送!

HTTP/2 兼容 HTTP/1,并且性能更好,在 兼容性性能 上都有所提升!

Tripple 协议是 Dubbo3 推出的主力协议,Tripple 的含义就是三,表示是第三代,Tripple 协议的特点:

1、Tripple 协议是 Dubbo3 设计的基于 HTTP2 的 RPC 通信协议规范, 通用性 能有所提升,并且由于是基于 HTTP/2 的,因此 性能 上也要比 HTTP/1.x 要好一些

2、Tripple 协议支持 流式调用

由于 Tripple 协议是基于 HTTP/2 的,因此这里对 HTTP/2 协议再介绍一下

  • 介绍一下 HTTP/2 协议

HTTP/2 协议是对 HTTP/1 协议的升级,HTTP/1 的缺点就是任何一个普通的 HTTP 请求,就算只发送很短的一个字符串,也要带上一个请求头,并且这个请求头比较大,占用多个字节,导致数据传输效率不高!

HTTP/1 协议的请求格式如下:

image-20240221162128239

可以看到下边红色部分的实体也就是我们需要传输的数据

而上边都是请求头中的一些数据,像一些空格、换行符都是没有必要存在的字符,因此在 HTTP/2 中做了优化

HTTP/2 中所做的优化:

1、HTTP/2 中 将请求和响应数据分割为更小的帧

2、并且 引入 HPACK 算法对标头压缩 ,减小标头大小

3、并且 支持 Stream

image-20240221172508947

1、帧长度:总共 24 bit,表示的最大数字为 2^24bit = 16M,所以一个帧最大为:9B(头部) + 16M(内容)

2、帧类型,8bit,分为数据帧和控制帧

​ 2.1、数据帧分为:HEADERS 帧和 DATA 帧,用来传输请求头、请求体

​ 2.2、控制帧分为:SETTINGS、PING、PRIORITY,用来进行管理

3、标志位,8bit,可以用来表示当前帧是请求的最后一帧,方便服务端解析

4、流标识符,32bit,表示 Stream ID,最高位保留不用

5、实际传输的数据,如果帧类型是 HEADERS,则这里存储的就是请求头,如果帧类型是 DATA,则这里存储的就是请求体

  • HTTP/2 中的 Stream 流

HTTP/2 除了使用 HPACK 来压缩请求头的大小,他还支持 Stream,通过 Stream 可以极大程度上提升 HTTP/2 的并发度

在 HTTP/1 中,在一个 TCP 连接上,只能先发送一个请求,之后必须等这个请求相应之后,才可以发送第二个请求,这样速度太慢了

因此,在 HTTP/2 中,可以在一个 TCP 连接上维护多个 Stream,这样就可以并发的给服务端发送多个帧了

比如说,客户端要给服务端发送 3 个请求,如果只建立一个 Stream,那么每次只能发送 1 个请求,之后等拿到了响应结果之后,再发送第 2 个请求

如果建立了三个 Stream,客户端就可以使用三个线程,同时将 3 个请求通过这三个 Stream 发送给服务端去

  • 在 HTTP/2 中客户端发送请求的流程为:

1、新建 TCP 连接

2、新建一个 Stream:生成一个新的 StreamID,生成一个控制帧,帧里记录了生成的 StreamID,通过 TCP 连接发送出去

3、发送请求的请求头:生成要发送请求的 HEADERS 帧,使用 ASCII 编码,HPACK 进行压缩,将压缩后的数据放到帧的 Payload 区域,记录 StreamID,通过 TCP 连接发送出去

4、发送请求的请求体:将要发送请求的请求体中的数据按照指定的压缩算法(请求中指定的压缩算法,比如 gzip)进行压缩,使用压缩后的数据生成生成 DATA 帧,记录 StreamID,通过 TCP 连接发送出去

  • 在 HTTP/2 中服务端接收请求的流程为:

1、服务端从 TCP 连接中不断接受帧

2、当接收到控制帧,表示客户端要和服务端建立一个 Stream,服务端记录下来 StreamID,在 Dubbo3 中会生成一个 ServerStreamObserver 对象

3、当接收到 HEADERS 帧,取出 StreamID,找到对应的 ServerStreamObserver 对象,解压之后得到请求头,将请求头信息存入该 ServerStreamObserver 对象中

4、当接收到 DATA 帧,取出 StreamID,找到对应的 ServerStreamObserver 对象,将请求体解压之后,按照业务逻辑处理请求体

5、处理完之后,将结果生成 HEADERS 帧和 DATA 帧发送给客户端

  • 基于 HTTP/2 的数据帧机制,Tripple 协议支持 UNARY、SERVER_STREAM、BI_STREAM 三种模式

1、UNARY :最普通的,服务端接受完所有请求帧之后,才处理数据

2、SERVER_STREAM :服务端流式调用,服务端接收完所有请求帧之后,才处理数据,但是可以多次发送响应 DATA 帧给客户端

3、BI_STREAM :双端流式调用,客户端可以多次发送 DATA 帧,服务端不断接收 DATA 帧进行处理,并且将处理结果作为响应 DATA 帧多次发送给客户端,客户端收到之后,也会立即进行处理(也就是客户端和服务端都可以不断接收 DATA 帧,进行处理)

  • 接下来说一下 Tripple 协议支持的流式调用(就是基于 HTTP/2 的帧实现)

流式调用是在 Dubbo3.x 版本新增的,如果我们需要使用流式调用的话,需要自己定义对应的方法

首先引入一下需要使用的类 StreamObserver 的依赖:

<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-common</artifactId><version>3.0.7</version>
</dependency>

并且引入一下 Tripple 协议的依赖

<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-rpc-tripple</artifactId><version>3.0.7</version>
</dependency>

比如说,我们在 UserService 接口中定义了流式调用:

public interface UserService {String hello(String name);// 服务端流式调用default void helloServerStream(String name, StreamObserver<String> response) {}// 双端流式调用default StreamObserver<String> helloStream(StreamObserver<String> response) {return response;}
}

服务端流式调用 的话,返回值需要为 void ,参数中需要有 StreamObserver<String>

服务端对应接口实现方法为:

// UserServiceImpl implements UserService
@Override
public void sayHelloServerStream(String name, StreamObserver<String> response) {response.onNext(name + " hello");response.onNext(name + " world");response.onCompleted();
}

客户端调用者代码为:

userService.helloServerStream("11", new StreamObserver<String>(){@Overridepublic void onNext(String data) {// 服务端返回的数据}@Overridepublic void onError(Throwable throwable) {}@Overridepublic void onCompleted(String data) {// 服务端执行完毕}
})

双端流式调用 的话,返回值和参数都要有 StreamObserver

服务端对应接口实现方法为:

// UserServiceImpl implements UserService
@Override
public StreamObserver<String> sayHelloStream(StreamObserver<String> response) {return new StreamObserver<String>() {@Overridepublic void onNext(String data) {// 接收客户端发送的数据response.onNext("result:" + data);}@Overridepublic void onError(Throwable throwable) {}@Overridepublic void onCompleted(String data) {// 服务端执行完毕}}
}

客户端调用者代码为:

StreamObserver<String> streamObserver = userService.sayHelloStream(new StreamObserver<String>() {@Overridepublic void onNext(String data) {System.out.println("接收到响应数据:"+ data);}@Overridepublic void onError(Throwable throwable) {}@Overridepublic void onCompleted(String data) {// 接收数据完毕}
})
// 客户端发送数据
streamObserver.onNext("第一次发送数据");
streamObserver.onNext("第二次发送数据");
streamObserver.onCompleted();
  • 接下来总结一下 Tripple 协议中的流式调用的优点以及应用场景

首先,流式调用的优点就是 客户端可以多次向服务端发送消息,并且服务端也可以多次接收 ,通过 onNext 方法多次发送,比如用户在处理完一部分数据之后,将这一部分数据发送给服务端,之后再去处理下一部分数据,避免了一次发送很多数据的情况

流式调用的应用场景为:接口需要发送大量数据,这些数据通过一个 RPC 请求无法发送完毕,需要分批发送,并且需要保证发送的有序性

这篇关于【最新Dubbo3深入理解】Dubbo3核心Tripple协议详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/735807

相关文章

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

SQL Server 中的 WITH (NOLOCK) 示例详解

《SQLServer中的WITH(NOLOCK)示例详解》SQLServer中的WITH(NOLOCK)是一种表提示,等同于READUNCOMMITTED隔离级别,允许查询在不获取共享锁的情... 目录SQL Server 中的 WITH (NOLOCK) 详解一、WITH (NOLOCK) 的本质二、工作

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

Spring AI使用tool Calling和MCP的示例详解

《SpringAI使用toolCalling和MCP的示例详解》SpringAI1.0.0.M6引入ToolCalling与MCP协议,提升AI与工具交互的扩展性与标准化,支持信息检索、行动执行等... 目录深入探索 Spring AI聊天接口示例Function CallingMCPSTDIOSSE结束语