Dubbo Spring Cloud :服务调用的新选择

博文小编

2021-03-04


无论是Dubbo,还是Spring Cloud,大家可能都不会感到陌生。

那什么是Dubbo Spring Cloud呢?使用Dubbo Spring Cloud可以实现什么目的?基于其实现的路由和负载均衡又是怎样的呢?

本文就带大家来一探究竟!

以下节选自《深入理解Spring Cloud与实战》一书。

01什么是Dubbo Spring Cloud

Dubbo Spring Cloud是Spring Cloud Alibaba项目内部提供的一个可以使用Spring Cloud客户端RestTemplate或OpenFeign调用Dubbo服务的模块。

Apache Dubbo和Spring Cloud是两套架构完全不同的开发框架。

在讲解Dubbo Spring Cloud之前,我们先来看这个问题:Apache Dubbo暴露的服务都是接口级别的,而Spring Cloud暴露的服务是应用级别的,RestTemplate或OpenFeign发起调用服务都会有对应的URL Path、Query Parameter、Header等内容(这是HTTP协议调用),如何让这些内容关联Dubbo服务呢?

针对上述问题,Dubbo Spring Cloud实现了以应用为粒度的注册机制,每个Dubbo应用注册到注册中心后有且仅有一个服务。那么原先以接口为维度的那些接口信息去哪里了?

Dubbo Spring Cloud 定义了 DubboMetadataService 元数据服务的概念。这是一个专门用于存储 Dubbo 服务的元数据接口。DubboMetadataService 接口定义如下:

核心方法 getServiceRestMetadata 获取 Dubbo 服务的 Rest 元数据是指:当一个 Dubbo 服务同时也被 SpringMVC 相关注解修饰时,SpringMVC 相关注解修饰的内容就是这些 Rest 元数据。这些 Rest 元数据由 RestMethodMetadata 类修饰,比如,这个 Dubbo 服务 RestService 接口,其定义如下:

RestService服务对应的Rest元数据内容如下:

除了SpringMVC相关注解,当Dubbo服务自身也暴露Rest协议的时候,这些JAX-RS相关注解修饰的内容也会被解析成Rest元数据。比如,这个Dubbo服务RestService接口的代码如下:

RestService服务对应的Rest元数据内容如下:

从这两个例子的RestMethodMetadata内容可看出,SpringMVC和JAX-RS的Rest元数据是一致的。

Rest元数据出现的意义是为了匹配RestTemplate或OpenFeign的HTTP协议内容,匹配HTTP协议内容的目的是为了让HTTP协议内容关联上Dubbo服务。

使用RestTemplate或OpenFeign调用Dubbo服务会经历以下过程:
(1)根据服务名得到注册中心的Dubbo服务DubboMetadataService。

(2)使用DubboMetadataService里提供的getServiceRestMetadata方法获取要使用的Dubbo服务和对应的Rest元数据。

(3)基于Dubbo服务和Rest元数据构造GenericService。

(4)服务调用过程中使用GenericService发起泛化调用。

02调用Dubbo服务的步骤

下面是使用Dubbo Spring Cloud调用Dubbo服务的开发步骤。
(1)引入spring-cloud-starter-dubbo依赖。

加上依赖后,将注册中心改成 spring-cloud 注册中心:

(2)Provider 端接口加上 SpringMVC 相关注解或使用JAX-RS暴露Rest协议。

① 加上 SpringMVC 相关注解。

② 使用 JAX-RS 暴露 Rest 协议。

配置文件暴露 rest 协议:

接口使用 JAX-RS 注解修饰:

(3)Consumer 客户端加上 @DubboTransported 注解。

RestTemplate 和 OpenFeign 客户端都支持 @DubboTransported 注解。

RestTemplate 的使用方式如下:

OpenFeign 的使用方式如下:

(4)使用 RestTemplate 或 OpenFeign 调用 Dubbo 服务。

使用 RestTemplate调用的方式如下:

使用 OpenFeign调用的方式如下:

03再谈路由和负载均衡

基于Netflix Ribbon的Spring Cloud 负载均衡设计了以下两个核心接口:

路由对应的ILoadBalancer 接口,获取服务的 Server 实例列表。

负载均衡对应的 IRule 接口,从服务的 Server 实例列表中根据负载均衡算法获取一个实例。

Spring Cloud应用的流量控制本质上就是对 Server 列表的控制:

自定义 ILoadBalancer 接口,重写获取 Server 列表的逻辑(找出与当前请求匹配的 Server 列表)。

自定义 IRule 接口,从所有的 Server 列表里找出与当前请求匹配的 Server。

很明显,第一种基于 ILoadBalancer 的方式更加合理。

我们来看 Dubbo 路由 Router 的实现。

Route 方法会从 Invoker 列表中过滤一批 Invoker,得到另一批 Invoker 列表:

然后 Router 在RouterChain 里被使用:

RouterChain中的Router列表可以随意被添加,开发者可以基于SPI添加各式各样的Router。
笔者认为 Duboo 在路由侧的实现更加优雅。在Spring Cloud的设计中,Ribbon的路由设计与Request(流量)请求信息是解耦的,而 Dubbo 的 Router与Invocation(流量)是绑定的,这意味着路由过程可以直接基于流量特征进行动态操作,无须引入类似 ThreadLocal 的方式来传递流量特征。

另外,我们提到过Spring Cloud默认提供的ZoneAvoidanceRule这个IRule负载均衡策略,它内部会依赖ServerStats去根据Server状态摘除异常节点。

Spring Cloud 提供的其他 IRule 负载均衡策略并没有这个能力,如果想在自定义的 IRule 负载均衡也拥有摘除异常节点的能力,需要在代码里配合 ServerStats 使用。


更多相关内容请看《深入理解Spring Cloud与实战》一书!

《深入理解Spring Cloud与实战》
方剑 编著

Spring Cloud Alibba创始人倾力打造

巨献理论与实践相结合,核心知识点辅以案例讲解

本书共分10章,主要介绍Spring Cloud各个核心组件的设计原理,以及目前流行的Spring Cloud Alibba和 Netflix组件,并且剖析Spring Cloud对流处理、批处理,以及目前业界流行的Serverless的支持。在介绍各部分内容时,本书将理论与实践相结合,对每个核心知识点都给出了具体的案例应用,以帮助读者掌握核心组件的设计理念。
本书适合对Spring Cloud感兴趣并且想透彻理解Spring Cloud的读者阅读,也适合正在进行微服务选型的开发者阅读。


(扫码了解本书详情)

扫码进入本书交流群
与广大群友共同学习成长

读者评论

相关专题

相关博文