27

Dubbo对Spring Cloud说:来老弟,我要拥抱你

 3 years ago
source link: http://www.cnblogs.com/yinjihuan/p/12909886.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

项目地址

https://github.com/yinjihuan/kitty-cloud

前言

Kitty Cloud 开源后有以为朋友在 GitHub 上给我提了一个 issues,问为什么项目中要同时集成 Feign 和 Dubbo 两个框架来调用服务。今天就来聊一聊这个问题,然后讲下在 Kitty Cloud 中如何切换使用两种调用方式。

为什么要支持两种协议?

关于支持两种协议,我这个是一个开源项目,主要还是为了让使用者有更多的选择。当然框架本身不是我开发的,我只是使用者而已。

一种协议更统一化,两种协议混着用也不是不可以,具体还是看实际需求。比如你们内部有个 ID 分发的服务,调用量很高,就是对性能有这极致的要求。那么这个场景你就可以用 Rpc 来代替 Http 了。其他的正常使用 Http 协议就行,特殊场景的就用 Rpc 协议,互补而已。

用 Http 最好的点在于简单,传输内容就是文本,调试什么的都很方便。比如我要单独测试某个服务的接口,直接 PostMan 上调用这个 Http 接口就可以了,或者用 Swagger。

如果是 Dubbo 的 Rpc, 我可能需要用 telnet 来调用。

还有就是网关层的转发,如果是 Http 协议,直接转发过去了。如果是 Rpc 协议,网关内部需要转特殊处理,当然目前也有支持 Rpc 的网关。如果我们是两种协议,网关这边还是直接 Http 转发过去即可,内部服务之前想用什么协议让使用者自己决定。

其实在 Spring Cloud 慢慢进入企业后,有很多人都会遇到一个问题就是老的服务都是用 Dubbo 来通信的,如果转 Spring Cloud 技术栈,那么势必要去掉 Dubbo。

如果规模不大直接重构掉也没关系,但是对于大规模的应用,服务数量众多。不太可能一口吃成个胖子。就算要重构那也是一个一个的方式来,也就意味着在没重构完之前,老的服务还是 Dubbo,但有一些服务已经变成 Spring Cloud 体系了。这个时候兼容就是一个迫切需要解决的问题。

Spring Cloud Alibaba 的出现就为这个问题提供了完美的解决方案,同时支持两种协议,可以慢慢过渡迁移。

举例说明

下面通过一个例子来说明:

下图中有两个服务,最开始都是 Rpc 协议,服务 A 通过 Rpc 方式调用服务 B。

j2UBRzb.png!web

当我们将服务 B 重构成 Http 协议后,服务 A 就需要使用 Http 方式来调用服务 B。

FJRJ3mV.png!web

改造方案一

如果从实现需求上来讲,很简单,将服务 A 中调用的代码给出用 Feign 或者 RestTemplate 调用即可。但是这样也就意味着我重构了 B 服务,还需要改动 A 服务的代码,很有可能不止 A 一个服务在调用 B 服务,也许有几十个,那么我是不是得改几十个服务的调用方式。

显然这个方案不可行。你如果这样出方案,你老大一个眼神送给你,自己体会吧。。。。。

改造方案二

方案一既然被否了,那需求很明显嘛,就是你可以重构成 Spring Cloud 技术栈,但是你不能影响使用方。

要想不影响使用方,感觉只能从 Dubbo 的调用这块入手。也就是在 Dubbo 底层去扩展 ,如果目标服务是老的 Rpc 协议,那么调用方式保持不变即可。

如果目标服务变成新的 Http 协议,那么就需要使用新的方式去调用,只有在底层兼容了才不会影响使用方。

URfyiay.png!web

改造方案三

第三种方案也就是我们现在目前的方案,让服务 B 支持双协议,支持双协议后,那么所有的调用方都不用改变,因为 Rpc 的方式还支持。如果有新的服务可以使用 Http 来调用 B 服务的接口。

7V7riiU.png!web

怎么支持两种协议?

支持两种协议的核心在于 Dubbo Spring Cloud ,Dubbo Spring Cloud 作为 Spring Cloud Alibaba 中的最核心组件,基本上适配了 Spring Cloud 技术栈。

接口还是单独抽出来放在 API 模块中,FeignClient 相关定义在接口上。

imuIJ3F.png!web

在实现类中同时暴露两种协议,加上 Dubbo 的@Service 和@RestController 注解。

R3Ir2uI.png!web

使用方只需要注入接口即可调用,如果想使用 Feign 调用就用@Autowired 进行注入。

@Autowired
private UserRemoteService userRemoteService;

如果想使用 Dubbo 进行调用就用@Reference 进行注入。

@Reference(version = DubboConstant.VERSION_V100, group = DubboConstant.DEFAULT_GROUP, check = false)
private UserRemoteService userRemoteService;

还有一个很重要的配置在于需要将 Dubbo 的注册中心挂载到 Spring Cloud 注册中心上。

dubbo.registry.address=spring-cloud://localhost

高级玩法

目前虽然支持了双协议,但使用权交到了用户手里。就是你想用什么协议发起调用都可以,是通过硬编码的方式来处理的。

如果想灵活度更高的话,我们可以在 Dubbo 或者 Feign 的底层去扩展。比如基于 Feign 去扩展的话,那就是调用都是采用 Feign 的方式,不需要用@Reference 来注入客户端。我们可以通过集成配置中心,用配置的方式来指定采用哪种协议调用。在 Feign 底层通过配置内容决定是否要走 Rpc 调用。如果要走 Rpc 可以用 Dubbo 的泛化调用。

uuyu6vr.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK