写点什么

Dubbo 框架适配模块及实现原理

  • 2023-06-13
    湖南
  • 本文字数:1765 字

    阅读完需:约 6 分钟

适配 Dubbo 框架

Dubbo 是一款面向接口代理的高性能 RPC 调用框架,适用于数据量小但并发数大的服务调用场景,以及服务消费者机器数远大于服务提供者机器数的场景。


由于 Dubbo 与 Sentinel 出自同一家,因此 Sentinel 自然也会为 Dubbo 提供适配模块。


本节将介绍 Sentinel 的 Dubbo 适配模块的使用,并分析适配原理。

使用步骤

在项目的 pom.xml 依赖配置文件中添加 sentinel-apache-dubbo-adapter 模块的依赖配置,代码如下:

在导入依赖后,Dubbo 的服务接口和方法(包括调用端和服务端)就会成为 Sentinel 保护的资源。

Sentinel 适配 Dubbo 框架可支持两种限流粒度,不同粒度资源名称的生成规则不同。

  • 接口级别:资源名称为接口全限定名。

  • 方法级别:资源名称为接口全限定名+“:”+方法签名。


Sentinel 适配 Dubbo 框架可支持注册全局的 Fallback 处理器。在 Sentinel 抛出限流、熔断等 BlockException 时,Fallback 函数会被回调,可用于实现限流、熔断后的降级操作。在应用启动时,可以通过调用 DubboAdapterGlobalConfig#setConsumerFallback 方法注册,代码如下:

Sentinel 默认使用 Dubbo 配置项 dubbo.application.name 的值作为调用来源,由客户端在发起 RPC 调用时传递给服务端。如果需要针对某个调用来源限流,则限流规则的 limitApp 应该与客户端的 dubbo.application.name 配置一样。

适配原理

Dubbo 在采用分层架构设计实现解耦的同时方便了各层的扩展,总体可分为业务层、RPC 层和 Remote 层,而 RPC 层又可细分为代理层、注册中心层、集群负载层、监视器层和协议层。在 RPC 层中,协议层是核心层,也就是说,只要有 Protocol+Invoker+Exporter,就可以完成非透明的 RPC 远程调用。


无论是服务端还是客户端,都是通过实现相同的 RPC 接口来向外暴露服务及引用服务的。Dubbo 通过动态代理为接口生成代理类,代理类可将接口转换为 Invoker,将调用接口方法转换为调用 Invoker 的 invoke 方法,并将请求参数封装为 Invocation。而 Invoker 在暴露与引入的过程中又被包装器添加了过滤器,因此在向远程发起调用时,会先经过过滤器,在过滤器不过滤请求的情况下才会真正发起远程调用。


Sentinel 适配 Dubbo 框架的本质是向 Dubbo 注册自定义过滤器,在过滤器中使用 Sentinel 来包装 Invoker。

Dubbo 框架是由一个个组件构成的,每个组件实现的是不同分层的逻辑,同时 Dubbo 需要通过 SPI 机制加载所需的组件。Sentinel Dubbo Adapter 模块通过 Dubbo SPI 机制向 Dubbo 注册自定义的过滤器,并在源码的 resources/META-INF/dubbo 目录下的 org.apache.dubbo.rpc.Filter 配置文件中配置。


该文件配置的内容如下:

  • SentinelDubboConsumerFilter:Sentinel 适配 Dubbo 框架的过滤器,只在客户端生效。

  • SentinelDubboProviderFilter:Sentinel 适配 Dubbo 框架的过滤器,只在服务端生效。

  • DubboAppContextFilter:用于客户端向服务端传递调用来源,只在客户端生效。

1. 服务端

服务端通过 SentinelDubboProviderFilter 过滤器适配 Dubbo 框架,在 invoke 方法中使用 Sentinel 分别按接口粒度、方法粒度包装 RPC 请求,源码如下:



  1. 获取调用来源。

  2. 生成不同粒度的资源名称。

  3. 调用 ContextUtil#enter 方法,调用链入口名称为方法级别的资源名称。

  4. 为不同粒度资源调用 SphU#entry 方法,资源类型为 COMMON_RPC,流量类型为 IN。

  5. 当远程响应异常时,为不同粒度资源统计异常指标。

  6. 如果抛出 BlockException,则说明当前请求被拒绝,可调用注册的全局 Fallback 处理器完成降级逻辑处理。

  7. 当发起调用抛出异常时,为不同粒度资源分别统计异常指标。

  8. 为不同粒度资源分别调用 SphU#exit 方法。

  9. 调用 ContextUtil#exit 方法。

2. 客户端

客户端通过 SentinelDubboConsumerFilter 过滤器适配 Dubbo 框架,在 invoke 方法中使用 Sentinel 分别按接口粒度、方法粒度包装 RPC 请求,在不考虑适配异步调用的情况下,SentinelDubboConsumerFilter 与 SentinelDubboProviderFilter 在实现上没有多大差别。适配客户端还有一个 DubboAppContextFilter 过滤器,该过滤器用于向服务端传递调用来源。


DubboAppContextFilter 过滤器的源码如下:

在实际项目中,微服务之间的调用错综复杂,对于不同接口,客户端可能也是服务端,服务端可能也是客户端。因此,如果不需要注册 SentinelDubboConsumerFilter 过滤器或 SentinelDubboProviderFilter 过滤器,则可以在项目中添加如下配置以排除过滤器。


排除 Sentinel 适配 Dubbo 框架客户端的过滤器的配置如下:

排除 Sentinel 适配 Dubbo 框架服务端的过滤器的配置如下:


用户头像

加VX:bjmsb02 凭截图即可获取 2020-06-14 加入

公众号:程序员高级码农

评论

发布
暂无评论
Dubbo框架适配模块及实现原理_互联网架构师小马_InfoQ写作社区