微服务最佳实践,零改造实现 Spring Cloud & Apache Dubbo 互通

本文涉及的产品
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,182元/月
简介: 微服务最佳实践,零改造实现 Spring Cloud & Apache Dubbo 互通

作者:孙彩荣


很遗憾,这不是一篇关于中间件理论或原理讲解的文章,没有高深晦涩的工作原理分析,文后也没有令人惊叹的工程数字统计。本文以实际项目和代码为示例,一步一步演示如何以最低成本实现 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/

相关文章
|
18天前
|
数据可视化 Java BI
将 Spring 微服务与 BI 工具集成:最佳实践
本文探讨了 Spring 微服务与商业智能(BI)工具集成的潜力与实践。随着微服务架构和数据分析需求的增长,Spring Boot 和 Spring Cloud 提供了构建可扩展、弹性服务的框架,而 BI 工具则增强了数据可视化与实时分析能力。文章介绍了 Spring 微服务的核心概念、BI 工具在企业中的作用,并深入分析了两者集成带来的优势,如实时数据处理、个性化报告、数据聚合与安全保障。同时,文中还总结了集成过程中的最佳实践,包括事件驱动架构、集中配置管理、数据安全控制、模块化设计与持续优化策略,旨在帮助企业构建高效、智能的数据驱动系统。
将 Spring 微服务与 BI 工具集成:最佳实践
|
23天前
|
Java 数据库 数据安全/隐私保护
Spring 微服务和多租户:处理多个客户端
本文介绍了如何在 Spring Boot 微服务架构中实现多租户。多租户允许单个应用实例为多个客户提供独立服务,尤其适用于 SaaS 应用。文章探讨了多租户的类型、优势与挑战,并详细说明了如何通过 Spring Boot 的灵活配置实现租户隔离、动态租户管理及数据源路由,同时确保数据安全与系统可扩展性。结合微服务的优势,开发者可以构建高效、可维护的多租户系统。
252 127
|
18天前
|
存储 安全 Java
管理 Spring 微服务中的分布式会话
在微服务架构中,管理分布式会话是确保用户体验一致性和系统可扩展性的关键挑战。本文探讨了在 Spring 框架下实现分布式会话管理的多种方法,包括集中式会话存储和客户端会话存储(如 Cookie),并分析了它们的优缺点。同时,文章还涵盖了与分布式会话相关的安全考虑,如数据加密、令牌验证、安全 Cookie 政策以及服务间身份验证。此外,文中强调了分布式会话在提升系统可扩展性、增强可用性、实现数据一致性及优化资源利用方面的显著优势。通过合理选择会话管理策略,结合 Spring 提供的强大工具,开发人员可以在保证系统鲁棒性的同时,提供无缝的用户体验。
|
18天前
|
消息中间件 Java 数据库
Spring 微服务中的数据一致性:最终一致性与强一致性
本文探讨了在Spring微服务中实现数据一致性的策略,重点分析了最终一致性和强一致性的定义、优缺点及适用场景。结合Spring Boot与Spring Cloud框架,介绍了如何根据业务需求选择合适的一致性模型,并提供了实现建议,帮助开发者在分布式系统中确保数据的可靠性与同步性。
|
19天前
|
消息中间件 Java Kafka
消息队列比较:Spring 微服务中的 Kafka 与 RabbitMQ
本文深入解析了 Kafka 和 RabbitMQ 两大主流消息队列在 Spring 微服务中的应用与对比。内容涵盖消息队列的基本原理、Kafka 与 RabbitMQ 的核心概念、各自优势及典型用例,并结合 Spring 生态的集成方式,帮助开发者根据实际需求选择合适的消息中间件,提升系统解耦、可扩展性与可靠性。
消息队列比较:Spring 微服务中的 Kafka 与 RabbitMQ
|
19天前
|
Prometheus 监控 Java
日志收集和Spring 微服务监控的最佳实践
在微服务架构中,日志记录与监控对系统稳定性、问题排查和性能优化至关重要。本文介绍了在 Spring 微服务中实现高效日志记录与监控的最佳实践,涵盖日志级别选择、结构化日志、集中记录、服务ID跟踪、上下文信息添加、日志轮转,以及使用 Spring Boot Actuator、Micrometer、Prometheus、Grafana、ELK 堆栈等工具进行监控与可视化。通过这些方法,可提升系统的可观测性与运维效率。
日志收集和Spring 微服务监控的最佳实践
|
12天前
|
监控 安全 Java
Spring Cloud 微服务治理技术详解与实践指南
本文档全面介绍 Spring Cloud 微服务治理框架的核心组件、架构设计和实践应用。作为 Spring 生态系统中构建分布式系统的标准工具箱,Spring Cloud 提供了一套完整的微服务解决方案,涵盖服务发现、配置管理、负载均衡、熔断器等关键功能。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
55 1
|
19天前
|
jenkins Java 持续交付
使用 Jenkins 和 Spring Cloud 自动化微服务部署
随着单体应用逐渐被微服务架构取代,企业对快速发布、可扩展性和高可用性的需求日益增长。Jenkins 作为领先的持续集成与部署工具,结合 Spring Cloud 提供的云原生解决方案,能够有效简化微服务的开发、测试与部署流程。本文介绍了如何通过 Jenkins 实现微服务的自动化构建与部署,并结合 Spring Cloud 的配置管理、服务发现等功能,打造高效、稳定的微服务交付流程。
使用 Jenkins 和 Spring Cloud 自动化微服务部署
|
Dubbo Java 应用服务中间件
由浅入深Dubbo核心源码剖析SpringBoot整合使用
由浅入深Dubbo核心源码剖析SpringBoot整合使用
198 0
|
JSON Dubbo Java
微服务框架(二十)Dubbo Spring Boot 生产就绪特性
  此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。   本文为Dubbo Spring Boot 生产就绪特性

热门文章

最新文章

推荐镜像

更多