Dubbo3.3 Triple协议处理东西向流量

前言

Apache Dubbo 3.3 对 Triple 协议做了升级,现在 Dubbo 不仅可以处理东西向流量,也可以处理南北向流量。

**东西向流量(East-West Traffic) **

指数据中心或网络内部同级设备/服务之间的通信。例如,微服务之间的内部调用。

南北向流量(North-South Traffic)

指网络外部用户与内部服务之间的通信。例如,客户端访问微服务。

之前的 Dubbo 一般只用来处理服务内部的高性能RPC调用,外部用户要想访问 Dubbo 服务,只能再额外部署一个网关层,网关负责把 HTTP 协议转换成 dubbo 协议。这样一来,不仅网络多了一跳增加时延,维护难度也大大增加。

另外,由于需要在 Web 框架和 RPC 框架之间频繁切换,开发复杂度和性能均有影响,比如:

  • 针对 Web 框架和 RPC 框架的诸如:日志、监控、拦截器、异常处理等,都需要重复开发
  • Web 框架和 RPC 框架都有自己处理任务的线程池,系统需要在二者之间频繁切换,影响性能

Apache Dubbo 3.3 Triple X 协议的诞生,直接回应了这些痛点。支持东西向流量,只是 Triple X 其中一个特性,完整功能参考:Apache Dubbo 3.3 全新发布:Triple X 领衔,开启微服务通信新时代

安装&使用

最新的版本目前是3.3.5,如果只用 dubbo,引入下面一个依赖即可。

<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId><version>3.3.5</version>
</dependency>

RestService 服务开发,因为要处理南北向流量,需要通过@Mapping等注解声明请求路径和参数等信息。

@Mapping(path = "/")
public interface RestService {@Mapping(path = "/hello", method = HttpMethods.GET)String hello(@Param("name") String name);
}public class RestServiceImpl implements RestService {@Overridepublic String hello(String name) {return "hello " + name;}
}

接着,启动服务即可。如下代码,服务暴露的端口是 50000,协议名是简写的tri

public class Provider {public static void main(String[] args) {ServiceConfig<RestService> serviceConfig = new ServiceConfig<>();serviceConfig.setInterface(RestService.class);serviceConfig.setRef(new RestServiceImpl());ApplicationConfig applicationConfig = new ApplicationConfig("provider");applicationConfig.setQosEnable(false);DubboBootstrap.getInstance().application(applicationConfig).protocol(new ProtocolConfig("tri", 50000)).service(serviceConfig).registry(new RegistryConfig("N/A")).start().await();}
}

triple 默认支持 HTTP1和HTTP2,如果要使用HTTP3需要引入额外依赖。现在,通过IP+端口就可以直接以 http 协议访问服务了。

$ curl 127.0.0.1:50000/hello\?name=triple
"hello triple"

整合Spring Boot

单独用 Dubbo 开发比较少,一般都是整合 Spring Boot 一起用。要整合 Spring Boot,引入下面依赖:

<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.3.5</version>
</dependency>

application.yml配置 Dubbo 协议部分

dubbo:protocol:name: triport: 50000

Dubbo 默认支持 Spring Web 注解,所以用 Dubbo 写 Web API 和之前几乎没区别,如下所示:

没有@RestController,但是必须加@DubboService

@DubboService
@RequestMapping
public class MyRestController {@GetMapping("/hello")public String hello(@RequestParam("name") String name) {return "hello " + name;}
}

启动类上加@EnableDubbo启用 Dubbo,访问 50000 端口即可访问服务。

$ curl 127.0.0.1:50000/hello?name=triple
"hello triple"

分端口混合模式

如果旧项目已经用 Spring MVC 开发了一些 API,但是新的 API 想用 Dubbo 开发,可以用区分端口的混合模式部署。区分端口,也就是 Web 容器占用一个端口,Dubbo 占用一个端口,彼此之间互不干扰。

项目同时依赖spring-boot-starter-web和 Dubbo

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.3.5</version>
</dependency>

application.yml分别配置 Web 容器端口和 Dubbo 协议端口

server:port: 8080
dubbo:protocol:name: triport: 50000

这样一来,之前的 API 通过 8080 端口访问,Dubbo API 通过 50000 端口访问,互不影响。

一种更方便的写法,在 Controller 上同时加@Controller@DubboService注解,8080 和 50000 端口都可以访问这个 API。但是要注意,Spring MVC 的所有功能并非 Dubbo 都支持,实测下来发现 Spring 的Web拦截器和全局异常处理,通过Dubbo访问是不生效的。

同端口混合模式

如果不想 Dubbo 再额外占用端口,也可以采用不区分端口的混合模式部署。

引入下面这个依赖

<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-3-autoconfigure</artifactId><version>3.3.5</version>
</dependency>

application.yml把 triple 协议端口和server.port配置相同,Dubbo 将不再占用新端口,可复用 Spring Boot 已有 servlet 监听端口来接入 HTTP 流量,符合filter-url-patterns路径的请求会转交给 Dubbo 处理。

server:port: 8080
dubbo:protocol:name: triport: 8080triple:servlet:enabled: truefilter-url-patterns: /dubbo/*filter-order: -1000000

你可能会感到好奇,不监听新端口,Dubbo 是怎么处理请求的呢?

实际上,在引入上述依赖后,Spring 启动会触发 DubboTripleAutoConfiguration 自动装配,并向容器注册一个FilterRegistrationBean,它会向 Servlet 容器注册一个jakarta.servlet.Filter实现,只要它的优先级比默认的org.springframework.web.filter.OncePerRequestFilter高,就可以提前接管 Web 流量。

Dubbo 注册的是 TripleFilter,只要请求路径匹配,它将接管请求,不通过后续 Filter。并且内置了 HTTP1和HTTP2的支持。

异常处理

全局异常处理是基本操作,服务端处理异常需要返回一个友好的信息给到客户端。

默认发生异常时,Dubbo 会封装成 ErrorResponse 对象返回

@Data
public class ErrorResponse {private String status;private String message;
}

默认 status = 500,message 是异常信息,例如:

{"message": "name is null","status": "500"
}

但是,一般系统会封装自己的错误码和错误信息,而且会区分是一般的业务异常,还是系统异常。Dubbo 的处理方式显得过于简单粗暴,所以我们要定义自己的异常处理器。

Triple 异常处理器实现 org.apache.dubbo.remoting.http12.ExceptionHandler 接口,如下所示:

@Activate
public class CustomExceptionHandler implements ExceptionHandler<Throwable, HttpResult> {@Overridepublic HttpResult handle(Throwable throwable, RequestMetadata metadata, MethodDescriptor descriptor) {if (throwable instanceof BizException exception) {return HttpResult.builder().status(200).body(JSON.toJSONString(R.failed(exception.getCode(), exception.getMessage()))).build();}return HttpResult.builder().status(500).body("system error").build();}
}

Tips:CustomExceptionHandler 需要 Dubbo SPI 激活

如果发生业务异常,会正常返回 HttpStatus=200,body 示例:

{"code": 400,"message": "name is too long"
}

如果是非业务异常,会返回 HttpStatus=500,body:system error

过滤器

之前 dubbo 协议的过滤器是基于 org.apache.dubbo.rpc.Filter 接口实现的,参数只能拿到 Invoker 和 Invocation。

Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException;

这对基于 HTTP 的 triple 协议来说显然不够友好,HTTP 协议的拦截我们一般会基于 Query Parameters 或 Headers 去做一些诸如:参数验签、认证授权、路由等操作,我们更熟悉的应该是 HttpRequest HttpResponse 对象。

所以,Dubbo 也提供了新的过滤器接口 org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter,如下所示,过滤器实现验签、鉴权等操作,前提是需要 SPI 激活。

@Activate(group = "provider", order = 100)
public class CustomRestFilter implements RestFilter {@Overridepublic void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) throws Exception {// todo 参数验签...String sign = request.header("sign");// todo 认证鉴权...String authorization = request.header("Authorization");chain.doFilter(request, response);}
}

RestFilter 还有一个内部接口 Listener,用于修改响应结果,或者发生异常时返回自定义信息。

interface Listener {default void onResponse(Result result, HttpRequest request, HttpResponse response) throws Exception {}default void onError(Throwable t, HttpRequest request, HttpResponse response) throws Exception {}
}

尾巴

Apache Dubbo 3.3 通过升级 Triple 协议,不仅支持东西向流量(服务间调用),也扩展至南北向流量(外部访问服务)。这一改进消除了额外部署网关层的需求,减少了时延和维护难度。Triple协议默认支持HTTP1/HTTP2,并可选择支持HTTP3。

异常处理和过滤器功能也得到了优化,提供了更灵活、友好的处理方式。Triple 协议通过 SPI 激活的ExceptionHandlerRestFilter接口,使开发者可以自定义异常响应和请求拦截。

这些改进使Dubbo在微服务架构中更具灵活性和扩展性,适应多样化的应用场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95943.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统核心特点详解:从并发到分布式,一文搞懂考研必备知识

操作系统核心特点详解&#xff1a;从并发到分布式&#xff0c;一文搞懂考研必备知识 大家好&#xff0c;今天咱们来聊聊操作系统&#xff08;OS&#xff09;这个计算机世界的“大管家”。想象一下&#xff0c;你的电脑就像一个忙碌的厨房&#xff0c;操作系统就是那个厨师长&am…

2025精选5款AI视频转文字工具,高效转录秒变文字!

视频转文本的需求早已渗透到生活的方方面面&#xff1a;网课学习需要提取课件台词、会议记录想快速整理要点、追剧时急需生肉转字幕…… 手动记录不仅费时&#xff0c;还容易遗漏关键信息。今天就分享5款实用工具&#xff0c;从免费到专业全覆盖&#xff0c;几步操作就能让视频…

MyBatis Example模式SQL注入风险

在使用MyBatis逆向工程生成的Example查询模式时&#xff0c;很多开发者看到XML中存在${}占位符就会担心SQL注入问题。但实际上&#xff0c;存在${}并不等同于存在SQL注入风险。本文将详细分析何时会存在真正的注入风险。 存在SQL注入的两个关键前提 前提一&#xff1a;Criteria…

宝塔PostgreSQL安装pgvecto插件contrib包实现向量存储

1. 宝塔安装 首先确保你的宝塔已经安装了 PostgreSQL。 安装好后是能看到上面这个界面的。 我安装的是 16.1 版本&#xff0c;下面的教程讲的也是 16.1 版本的。 2.开放防火墙的端口号 5432 3.允许外部访问所有数据库 4.设置超级管理员用户密码 用户名默认为&#xff1a;po…

麒麟系统 doc转pdf

# 安装LibreOffice&#xff08;如果尚未安装&#xff09; sudo apt update sudo apt install libreoffice# 将DOC转换为PDF libreoffice --headless --convert-to pdf 你的文档.doc# 或者指定输出目录 libreoffice --headless --convert-to pdf --outdir /输出目录 你的文档.do…

Python实现生成矩形框、三角形框、六边形框和圆环点云

本节我们分享上节提到的不填充点云。在点云处理、计算机视觉与工业检测中&#xff0c;几何轮廓&#xff08;边框/环&#xff09;点云比实心点云更能反映物体的边缘特征、结构骨架与形貌突变区域。Python 借助 NumPy 即可快速生成矩形边框、三角形边框、六边形边框与圆环点云&am…

2025年本体论:公理与规则的挑战与趋势

摘要本文章旨在深入探讨本体论&#xff08;Ontology&#xff09;中公理&#xff08;Axioms&#xff09;与规则&#xff08;Rules&#xff09;的核心概念、技术实现、验证方法、性能评估及其在2025年的前沿趋势与挑战。公理与规则是构建严谨、一致知识模型的逻辑基石&#xff0c…

【51单片机】【protues仿真】基于51单片机PM2.5空气质量检测系统

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 一、主要功能 1、LCD1602液晶显示 2、按键​设置阈值 3、PM2.5大于阈值时启动声光警报 二、使用步骤 基于51单片机的PM2.5空气质量检测系统通常采用STC89C51/52作为核心控制器&#xff0c;结合…

【目录-单选】鸿蒙HarmonyOS开发者基础

用哪一种装饰器修饰的组件可作为页面入口组件&#xff1f;Look at the answer下面是ArkTS中类名、枚举名推荐的代码风格是 Look at the answer向服务器提交表单数据&#xff0c;以下哪种请求方式比较合适 Look at the answer使用http发起网络请求&#xff0c;需要以下哪种权限&…

maven【maven】技术详解

MavenMaven的本质是项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型&#xff08;POM&#xff09;Project Object Model&#xff1a;项目对象管理模型作用&#xff1a; 项目构建&#xff1a;提供标准的、跨平台的自动化项目构建方式依赖管理&#xff1a;方…

【操作系统-Day 25】死锁 (Deadlock):揭秘多线程编程的“终极杀手”

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…

【嵌入式C语言】七

8.4函数的声明和定义声明一个函数意味着向编译器描述函数名、返回值、参数个数和类型&#xff0c;但并不会为函数分配存储空间定义一个函数意味着在声明变量的同时还要有具体的实现&#xff0c;并且会为函数分配存储空间8.5多源文件的函数声明和定义8.6预处理指令#Include#incl…

hardhat3 源神 -- 启动!

Hardhat 项目开发环境搭建完整指南 1. 从 GitHub 下载项目 # 使用 SSH 方式克隆&#xff08;需要配置 SSH key&#xff09; git clone gitgithub.com:NomicFoundation/hardhat.git# 或使用 HTTPS 方式 git clone https://github.com/NomicFoundation/hardhat.git# 进入项目目录…

遇到 Git 提示大文件无法上传确实让人头疼

遇到 Git 提示大文件无法上传确实让人头疼&#xff0c;但别担心&#xff0c;我们可以一步步来解决。为了让你更清晰地了解整个流程&#xff0c;我先用一个表格来概括主要步骤&#xff1a;步骤核心操作关键命令/工具示例 (用于删除历史中的大文件)1. 定位大文件使用 Git 命令或工…

机器人控制器开发(传感器层——奥比大白相机适配)

编译OrbbecSDK_ROS2的代码 执行命令 colcon buildros2 launch orbbec_camera dabai.launch.py问题1&#xff1a; 运行时报错&#xff1a; [component_container-1] [ERROR] [1757153916.450795107] [camera.camera_container]: Failed to load library: Could not load library…

C语言(长期更新)第15讲 指针详解(五):习题实战

C语言&#xff08;长期更新&#xff09;第15讲 指针详解&#xff08;五&#xff09;&#xff1a;习题实战 跟着潼心走&#xff0c;轻松拿捏C语言&#xff0c;困惑通通走&#xff0c;一去不回头~欢迎开始今天的学习内容&#xff0c;你的支持就是博主最大的动力。博主主页&#…

数据仓库概要

什么是数据仓库&#xff1f; 数据仓库是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合&#xff0c;用于支持管理决策。 核心特征 1. 面向主题 数据仓库围绕核心业务主题&#xff08;如客户、产品、销售、财务&#xff09;来组织数据&#xff0c;而不是围绕具体的…

python库 Py2exe 的详细使用(将 Python 脚本变为Windows独立软件包)

更多内容请见: python3案例和总结-专栏介绍和目录 文章目录 一、Py2exe 概述 1.1 Py2exe介绍 1.2 Py2exe安装 1.3 替代工具推荐 二、基础使用 2.1 编写打包脚本 2.2 执行打包命令 2.3 完整案例 2.4 配置选项详解 2.5 构建和分发 三、高级配置 3.1 包含隐藏导入 3.2 处理特殊包…

CuTe C++ 简介02,gemm_device cuda kernel 的实现

《CuTe C 简介01&#xff0c;从示例开始 》 中&#xff0c;最后看到了 计算 gemm 的cuda kernel&#xff0c;使用 NVIDIA CUTLASS 的 CUTe (CUDA Tile) 库实现的高性能 GEMM (通用矩阵乘法) CUDA kernel。接下来解释一下这个内核的各个部分。文末再贴一遍代码&#xff0c;方便查…

万代《宝可梦》主题新品扭蛋公开!史上最大尺寸

使用jQuery的常用方法与返回值分析 jQuery是一个轻量级的JavaScript库&#xff0c;旨在简化HTML文档遍历和操作、事件处理以及动画效果的创建。本文将介绍一些常用的jQuery方法及其返回值&#xff0c;帮助开发者更好地理解和运用这一强大的库。 1. 选择器方法 jQuery提供了多种…