共计 5175 个字符,预计需要花费 13 分钟才能阅读完成。
作者:孙彩荣
很遗憾,这不是一篇对于中间件实践或原理解说的文章,没有浅近艰涩的工作原理剖析,文后也没有令人惊叹的工程数字统计。 本文以理论我的项目和代码为示例,一步一步演示如何以最低老本实现 Apache Dubbo 体系与 Spring Cloud 体系的互通,进而实现不同微服务体系的混合部署、迁徙等,帮忙您解决理论架构及业务问题。
背景与指标
如果你在微服务开发过程中正面临以下一些业务场景须要解决,那么这篇文章能够帮到您:
- 您曾经有一套基于 Dubbo 构建的微服务利用,这时你须要将局部服务通过 REST HTTP 的模式(非接口、办法模式)公布进来,供一些规范的 HTTP 端调用(如 Spring Cloud 客户端),整个过程最好是不必改代码,间接为写好的 Dubbo 服务加一些配置、注解就能实现。
- 您曾经有一套基于 Spring Cloud 构建的微服务体系,而后又构建了一套 Dubbo 体系的微服务,你想两套体系共存,因而当初两边都须要调用到对方公布的服务。也就是 Dubbo 利用作为生产方要调用到 Spring Cloud 公布的 HTTP 接口,Dubbo 利用作为提供方还能公布 HTTP 接口给 Spring Cloud 调用。
- 出于一些历史起因,你正布局从一个微服务体系迁徙到另外一个微服务体系,前提条件是要保障两头过程的平滑迁徙。
对于以上几个场景,咱们都能够借助 Dubbo3 内置的 REST 编程范式反对实现,这让 Dubbo 既能够作为生产方调用 HTTP 接口的服务,又能够作为提供方对外公布 REST 格调的 HTTP 服务,同时整个编码过程反对业界罕用的 REST 编程范式(如 JAX-RS、Spring MVC 等),因而能够做到根本不改变任何代码的状况下实现 Dubbo 与 Spring Cloud 体系的相互调用。
- 对于这一部分更多的设计与实践论述请参见这里的博客文章 [ 1]
- 对于 Dubbo REST 的更多配置形式请参见 rest 应用参考手册 [ 2]
示例一:Dubbo 调用 Spring Cloud
在曾经有一套 Spring Cloud 微服务体系的状况下,演示如何应用 Dubbo 调用 Spring Cloud 服务(蕴含主动的地址发现与协定传输)。在注册核心方面,本示例应用 Nacos 作为注册核心,对于 Zookeeper、Consul 等两种体系都反对的注册核心同样实用。
构想你曾经有一套 Spring Cloud 的微服务体系,当初咱们将引入 Dubbo 框架,让 Dubbo 利用可能失常的调用到 Spring Cloud 公布的服务。本示例残缺源码请参见 samples/dubbo-call-sc [ 3]。
启动 Spring Cloud Server
示例中 Spring Cloud 利用的构造如下:
利用配置文件如下:
server:
port: 8099
spring:
application:
name: spring-cloud-provider-for-dubbo
cloud:
nacos:
serverAddr: 127.0.0.1:8848 #注册核心
以下是一个非常简单的 Controller 定义,公布了一个 /users/list/ 的 http 端点。
@RestController
@RequestMapping("/users")
public class UserController {@GetMapping("/list")
public List<User> getUser() {return Collections.singletonList(new User(1L, "spring cloud server"));
}
}
启动 SpringCloudApplication,通过 cURL 或浏览器拜访 http://localhost:8099/users/list 能够测试利用启动胜利。
应用 Dubbo Client 调用服务
Dubbo client 也是一个规范的 Dubbo 利用,我的项目根本构造如下:
其中,一个比拟要害的是如下接口定义(失常状况下,以下接口能够间接从原有的 Spring Cloud client 利用中原样拷贝过去即可,无需做任何批改)。
如果之前没有基于 OpenFeign 的 Spring Cloud 生产端利用,那么就须要自行定义一个接口,此时不肯定要应用 OpenFeign 注解,应用 Spring MVC 规范注解即可。
通过 DubboReference 注解将 UserServiceFeign 接口注册为 Dubbo 服务。
@DubboReference
private UserServiceFeign userService;
接下来,咱们就能够用 Dubbo 规范的形式对服务发动调用了。
List<User> users = userService.users();
通过 DubboConsumerApplication 启动 Dubbo 利用,验证能够胜利调用到 Spring Cloud 服务。
示例二:Spring Cloud 调用 Dubbo
在接下来的示例中,咱们将展现如何将 Dubbo server 公布的服务凋谢给 Spring Cloud client 调用。
示例的相干源码在 samples/sc-call-dubbo [ 4]
启动 Dubbo Server
Dubbo server 利用的代码构造非常简单,是一个典型的 Dubbo 利用。
相比于一般的 Dubbo 服务定义,咱们要在接口上加上如下规范 Spring MVC 注解:
@RestController
@RequestMapping("/users")
public interface UserService {@GetMapping(value = "/list")
List<User> getUsers();}
除了以上注解之外,其余服务公布等流程都统一,应用 DubboService 注解公布服务即可:
@DubboService
public class UserServiceImpl implements UserService {
@Override
public List<User> getUsers() {return Collections.singletonList(new User(1L, "Dubbo provider!"));
}
}
在服务配置上,特地留神咱们须要将服务的协定配置为 rest protocol: rest,地址发现模式应用 register-mode: instance:
dubbo:
registry:
address: nacos://127.0.0.1:8848
register-mode: instance
protocol:
name: rest
port: 8090
启动 Dubbo 利用,此时拜访以下地址能够验证服务运行失常:http://localhost:8090/users/list
应用 Spring Cloud 调用 Dubbo
应用 OpenFeign 开发一个规范的 Spring Cloud 利用,即可调用以上公布的 Dubbo 服务,我的项目代码构造如下:
其中,咱们定义了一个 OpenFeign 接口,用于调用下面公布的 Dubbo rest 服务。
@FeignClient(name = "dubbo-provider-for-spring-cloud")
public interface UserServiceFeign {@RequestMapping(value = "/users/list", method = RequestMethod.GET)
List<User> getUsers();}
定义以下 controller 作为 OpenFeign 和 RestTemplate 测试入口:
public class UserController {
private final RestTemplate restTemplate;
private final UserServiceFeign userServiceFeign;
public UserController(RestTemplate restTemplate,
UserServiceFeign userServiceFeign) {
this.restTemplate = restTemplate;
this.userServiceFeign = userServiceFeign;
}
@RequestMapping("/rest/test1")
public String doRestAliveUsingEurekaAndRibbon() {
String url = "http://dubbo-provider-for-spring-cloud/users/list";
System.out.println("url:" + url);
return restTemplate.getForObject(url, String.class);
}
@RequestMapping("/rest/test2")
public List<User> doRestAliveUsingFeign() {return userServiceFeign.getUsers();
}
}
依据以上 Controller 定义,咱们能够别离拜访以下地址进行验证:
- OpenFeign 形式: http://localhost:8099/dubbo/rest/test1
- RestTemplage 形式: http://localhost:8099/dubbo/rest/test2
为 Dubbo Server 公布更多的服务
咱们能够利用 Dubbo 的多协定公布机制,为一些服务配置多协定公布。接下来,咱们就为下面提到的 Dubbo server 服务减少 dubbo tcp 协定公布,从而达到以下部署成果,让这个 Dubbo 利用同时服务 Dubbo 微服务体系和 Spring Cloud 微服务体系。
为了实现这个成果,咱们只须要在配置中减少多协定配置即可:
dubbo:
protocols:
- id: rest
name: rest
port: 8090
- id: dubbo
name: dubbo
port: 20880
同时,服务注解中也配置为多协定公布:
@DubboService(protocol="rest,dubbo")
public class UserServiceImpl implements UserService {}
这样,咱们就胜利的将 UserService 服务以 dubbo 和 rest 两种协定公布了进来(多端口多协定的形式),dubbo 协定为 Dubbo 体系服务,rest 协定为 Spring Cloud 体系服务。
留神: Dubbo 为多协定公布提供了单端口、多端口两种形式,这样的灵活性对于不同部署环境下的服务会有比拟大的帮忙。在确定您须要的多协定公布形式前,请提仔细阅读以下多协定配置 [ 5] 文档。
总结
基于 Dubbo 的 rest 编程范式、多协定公布等个性,能够帮忙你轻松的实现 Dubbo 服务的 http 协定公布,让后端服务基于 RPC 高效通信的同时,可能更容易的与 http 服务体系买通,本示例通过 Dubbo 与 Spring Cloud 两套体系的共存、互通示例十分清晰的演示了编码过程。
此局部内容的正式版本将在 Dubbo 3.3.0 版本正式公布,同时还蕴含 Triple 协定的重磅降级,敬请期待!
相干链接:
[1] 博客文章
https://cn.dubbo.apache.org/zh-cn/blog/2023/01/05/dubbo-%e8%bf%9e%e6%8e%a5%e5%bc%82%e6%9e%84%e5%be%ae%e6%9c%8d%e5%8a%a1%e4%bd%93%e7%b3%bb-%e5%a4%9a%e5%8d%8f%e8%ae%ae%e5%a4%9a%e6%b3%a8%e5%86%8c%e4%b8%ad%e5%bf%83/
[2] rest 应用参考手册
https://cn.dubbo.apache.org/zh-cn/overview/reference/proposals/protocol-http/
[3] samples/dubbo-call-sc
https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-springcloud/dubbo-call-sc
[4] samples/sc-call-dubbo
https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-springcloud/sc-call-dubbo
[5] 多协定配置
https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-protocols/