带你读《Apache Dubbo微服务开发从入门到精通》——三、 网关(7)

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
性能测试 PTS,5000VUM额度
简介: 带你读《Apache Dubbo微服务开发从入门到精通》——三、 网关(7)

《Apache Dubbo微服务开发从入门到精通》——服务治理与生态——三、 网关(6) https://developer.aliyun.com/article/1223986


c) 流程分析

 

流程分析是从源码的角度,展示服务注册流程,数据同步流程和服务调用流程。

 

服务注册流程

 

读取dubbo服务

 

使用注解@ShenyuDubboClient标记需要注册到网关的dubbo服务。

 

注解扫描通过ApacheDubboServiceBeanListener完成,它实现了ApplicationListener接口,在Spring容器启动过程中,发生上下文刷新事件时,开始执行事件处理方法onApplicationEvent()。在重写的方法逻辑中,读取Dubbo服务ServiceBean,构建元数据对象和URI对象,并向shenyu-admin注册。

 

具体的注册逻辑由注册中心实现,请参考客户端接入原理

 

处理注册信息

 

客户端通过注册中心注册的元数据和URI数据,在shenyu-admin端进行处理,负责存储到数据库和同步给shenyu网关。Dubbo插件的客户端注册处理逻辑在ShenyuClientRegisterDubboServiceImpl中。继承关系如下:

 

image.png

 

ShenyuClientRegisterService:客户端注册服务,顶层接口

FallbackShenyuClientRegisterService:注册失败,提供重试操作

AbstractShenyuClientRegisterServiceImpl:抽象类,实现部分公共注册逻辑

ShenyuClientRegisterDubboServiceImpl:实现`Dubbo`插件的注册

 

注册信息包括选择器,规则和元数据。

 

整体的dubbo服务注册流程如下:

 

image.png

 

数据同步流程

 

admin更新数据

 

假设在在后台管理系统中,新增一条选择器数据,请求会进入SelectorController类中的createSelector()方法,它负责数据的校验,添加或更新数据,返回结果信息。

 

在SelectorServiceImpl类中通过createOrUpdate()方法完成数据的转换,保存到数据库,发布事件,更新upstream。

 

在Service类完成数据的持久化操作,即保存数据到数据库。发布变更数据通过eventPublisher.publishEvent()完成,这个eventPublisher对象是一个ApplicationEventPublisher类,这个类的全限定名是org.springframework.context.ApplicationEventPublisher,发布数据的功能正是是通过Spring相关的功能来完成的。

 

当事件发布完成后,会自动进入到DataChangedEventDispatcher类中的onApplicationEvent()方法,根据不同数据类型和数据同步方式进行事件处理。

 

网关数据同步

 

网关在启动时,根据指定的数据同步方式加载不同的配置类,初始化数据同步相关类。

 

在接收到数据后,进行反序列化操作,读取数据类型和操作类型。不同的数据类型,有不同的数据处理方式,所以有不同的实现类。但是它们之间也有相同的处理逻辑,所以可以通过模板方法设计模式来实现。相同的逻辑放在抽象类AbstractDataHandler中的handle()方法中,不同逻辑就交给各自的实现类。

 

新增一条选择器数据,是新增操作,会进入到SelectorDataHandler.doUpdate()具体的数据处理逻辑中。

 

在通用插件数据订阅者CommonPluginDataSubscriber,负责处理所有插件、选择器和规则信息

 

将数据保存到网关的内存中,BaseDataCache是最终缓存数据的类,通过单例模式实现。选择器数据就存到了SELECTOR_MAP这个Map中。在后续使用的时候,也是从这里拿数据。

 

上述逻辑用流程图表示如下:

 

image.png

 

服务调用流程

 

在Dubbo插件体系中,类继承关系如下:

 

image.png

 

注:

ShenyuPlugin:顶层接口,定义接口方法

AbstractShenyuPlugin:抽象类,实现插件共有逻辑

AbstractDubboPlugin:dubbo插件抽象类,实现dubbo共有逻辑(ShenYu网关支持ApacheDubbo和AlibabaDubbo)

ApacheDubboPlugin:ApacheDubbo插件。

 

org.apache.shenyu.web.handler.ShenyuWebHandler.DefaultShenyuPluginChain#execute()

 

通过ShenYu网关代理后,请求入口是ShenyuWebHandler,它实现了org.springframework.web.server.WebHandler接口,通过责任链设计模式将所有插件连接起来。

 

org.apache.shenyu.plugin.base.AbstractShenyuPlugin#execute()

 

当请求到网关时,判断某个插件是否执行,是通过指定的匹配逻辑来完成。在execute()方法中执行选择器和规则的匹配逻辑。

 

org.apache.shenyu.plugin.global.GlobalPlugin#execute()

 

最先被执行的是GlobalPlugin,它是一个全局插件,在execute()方法中构建上下文信息。

 

org.apache.shenyu.plugin.base.RpcParamTransformPlugin#execute()

 

接着被执行的是RpcParamTransformPlugin,它负责从http请求中读取参数,保存到exchange中,传递给rpc服务。在execute()方法中,执行该插件的核心逻辑:从exchange中获取请求信息,根据请求传入的内容形式处理参数。

 

org.apache.shenyu.plugin.dubbo.common.AbstractDubboPlugin

 

然后被执行的是DubboPlugin。在doExecute()方法中,主要是检查元数据和参数。在doDubboInvoker()方法中设置特殊的上下文信息,然后开始dubbo的泛化调用。

 

在genericInvoker()方法中:

 

获取ReferenceConfig对象

获取泛化服务GenericService对象

构造请求参数pair对象

发起异步的泛化调用。

 

通过泛化调用就可以实现在网关调用dubbo服务了。

 

ReferenceConfig对象是支持泛化调用的关键对象 ,它的初始化操作是在数据同步的时候完成的。

 

org.apache.shenyu.plugin.response.ResponsePlugin#execute()

 

最后被执行的是ResponsePlugin,它统一处理网关的响应结果信息。处理类型由MessageWriter决定,类继承关系如下:

 

image.png

 

注:

MessageWriter:接口,定义消息处理方法

NettyClientMessageWriter:处理`Netty`调用结果

RPCMessageWriter:处理`RPC`调用结果

WebClientMessageWriter:处理`WebClient`调用结果

 

Dubbo服务调用,处理结果是RPCMessageWriter。

 

org.apache.shenyu.plugin.response.strategy.RPCMessageWriter#writeWith()

 

在writeWith()方法中处理响应结果,获取结果或处理异常。

 

分析至此,关于Dubbo插件的源码分析就完成了,分析流程图如下:

 

image.png

 

4) 小结

 

本文从实际案例出发,由浅入深分析了ShenYu网关对Dubbo服务的代理过程。涉及到的主要知识点如下:

 

通过责任链设计模式执行插件

使用模板方法设计模式实现AbstractShenyuPlugin,处理通用的操作类型

使用单例设计模式实现缓存数据类BaseDataCache

通过springboot starter即可引入不同的注册中心和数同步方式,扩展性很好

通过admin支持规则热更新,方便流量管控

Disruptor队列是为了数据与操作解耦,以及数据缓冲。

相关文章
|
10天前
|
Java 持续交付 微服务
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在现代后端开发中的应用,通过具体案例分析,揭示了其如何助力企业应对业务复杂性、提升系统可维护性和可扩展性。文章首先概述了微服务的核心概念及其优势,随后详细阐述了实施微服务过程中的关键技术选型、服务拆分策略、容错机制以及持续集成/持续部署(CI/CD)的最佳实践。最后,通过一个真实世界的应用实例,展示了微服务架构在实际项目中的成功应用及其带来的显著成效。 ####
|
17天前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
75 3
|
20天前
|
设计模式 API 开发者
探索现代后端开发:微服务架构与API设计
【10月更文挑战第6天】探索现代后端开发:微服务架构与API设计
|
3天前
|
缓存 运维 监控
后端开发中的微服务架构实践与挑战#### 一、
【10月更文挑战第22天】 本文探讨了微服务架构在后端开发中的应用实践,深入剖析了其核心优势、常见挑战及应对策略。传统后端架构难以满足快速迭代与高可用性需求,而微服务通过服务拆分与独立部署,显著提升了系统的灵活性和可维护性。文章指出,实施微服务需关注服务划分的合理性、通信机制的选择及数据一致性等问题。以电商系统为例,详细阐述了微服务改造过程,包括用户、订单、商品等服务的拆分与交互。最终强调,微服务虽优势明显,但落地需谨慎规划,持续优化。 #### 二、
|
9天前
|
监控 API 开发者
后端开发中的微服务架构实践与优化
【10月更文挑战第17天】 本文深入探讨了微服务架构在后端开发中的应用及其优化策略。通过分析微服务的核心理念、设计原则及实际案例,揭示了如何构建高效、可扩展的微服务系统。文章强调了微服务架构对于提升系统灵活性、降低耦合度的重要性,并提供了实用的优化建议,帮助开发者更好地应对复杂业务场景下的挑战。
14 7
|
6天前
|
运维 监控 API
后端开发中的微服务架构实践与挑战####
【10月更文挑战第19天】 本文将深入浅出地探讨微服务架构在后端开发中的应用,通过实例解析其核心理念、优势所在,以及实施过程中可能遭遇的挑战与应对策略。不同于传统单体应用,微服务以其轻量级、灵活性和可扩展性受到青睐,但同时也带来了服务间的通信复杂性、数据一致性等问题。通过本篇文章,读者将对微服务架构有一个全面而深入的理解,为实际项目中的选型与实施提供参考。 ####
|
10天前
|
负载均衡 监控 API
后端开发中的微服务架构实践
【10月更文挑战第15天】 在当今的软件开发领域,微服务架构已成为一种流行的技术趋势。本文将探讨微服务架构的基本概念、优势以及在实际后端开发中的应用。我们将通过具体案例分析,了解如何设计和实现一个高效的微服务系统,以及如何应对在实施过程中可能遇到的挑战。
24 1
|
12天前
|
消息中间件 监控 Kubernetes
后端开发中的微服务架构实践与挑战####
本文将深入探讨微服务架构在后端开发中的应用,通过实际案例分析其优势与面临的挑战。我们将从微服务的基本概念入手,逐步剖析其在现代软件开发中的重要性及实施过程中需注意的关键因素。无论你是后端开发的新手还是资深工程师,这篇文章都将为你提供有价值的见解和启发。 ####
|
25天前
|
消息中间件 监控 数据管理
后端开发中的微服务架构实践与挑战
在当今软件开发领域,微服务架构因其高度的模块化和灵活性而备受关注。它通过将应用程序分解为小型、独立的服务来运行,从而简化了开发、部署和扩展过程。本文将探讨微服务架构的基本概念、实践方法以及在实际应用中面临的挑战,旨在帮助读者更好地理解和应用这一现代技术趋势。
|
26天前
|
Kubernetes Docker 微服务
微服务实践k8s&dapr开发部署实验(1)服务调用(一)
微服务实践k8s&dapr开发部署实验(1)服务调用(一)
44 2

推荐镜像

更多