返回介绍

16.2 Spring Boot 集成 Dubbo

发布于 2025-04-26 13:53:54 字数 8475 浏览 0 评论 0 收藏

16.2.1 Dubbo 概述

Dubbo 是阿里巴巴 B2B 平台技术部开发的一款 Java 服务平台框架以及 SOA 治理方案。其功能主要包括:高性能 NIO 通信及多协议集成、服务动态寻址与路由、软负载均衡与容错、依赖分析与降级等。Dubbo 简单的底层框架如图 16-4 所示。

Registry 是服务注册与发现的注册中心, Provider 是暴露服务的服务提供方,Consumer 是调用远程服务的服务消费方,Monitor 是统计服务的调用次数和调用时间的监控中心,Container 是服务运行容器。Dubbo 简单的调用关系如下:

(1)服务容器 Container 负责启动、加载、运行服务提供者 Provider。

(2)服务提供者 Provider 在启动时,向注册中心 Registry 注册自己提供的服务。

(3)服务消费者 Consumer 在启动时,向注册中心 Registry 订阅自己所需的服务。

图 16-4 Dubbo 底层框架原理

(4)注册中心 Registry 返回服务提供者地址列表给消费者 Provider,如果有变更,注册中心 Registry 将基于长连接推送,变更数据给消费者 Consumer。

(5)服务消费者 Consumer 从提供者地址列表中基于软负载均衡算法选一台提供者进行调用,如果调用失败,就再选另一台调用。

(6)服务消费者 Consumer 和提供者 Provider 在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心 Monitor。

Dubbo 将注册 Registry 中心进行抽象,使得它可以外接不同的存储媒介给注册中心 Registry 提供服务,可以作为存储媒介的有 ZooKeeper、Memcached、Redis 等。引入 ZooKeeper 作为存储媒介,也就是把 ZooKeeper 的特性引进来。首先是负载均衡,单注册中心的承载能力是有限的,在流量达到一定程度的时候就需要分流,负载均衡就是为了分流而存在的。一个 ZooKeeper 群配合相应的 Web 应用就可以很容易达到负载均衡;然后是资源同步,单单有负载均衡还不够,节点之间的数据和资源需要同步,ZooKeeper 集群就天然具备这样的功能;最后是命名服务,将树状结构用于维护全局的服务地址列表,服务提供者在启动的时候,向 ZooKeeper 的指定节点目录写入自己的 URL 地址,这个操作就完成了服务的发布。ZooKeeper 其他特性还有 Mast 选举、分布式锁等。ZooKeeper 的知识在 16.1 节中已经简单地介绍了,这里就不再重复叙述。

16.2.2 服务与接口拆分思路

截至 16 章,my-spring-boot 项目已经集成很多技术,也定义了很多接口。但是对于真实的项目来说,特别是对于互联网公司的项目来说,my-spring-boot 这个大的服务承载的内容太多,诸多服务接口(比如 AyUserService、AyMoodService、AyRoleService 等)糅合在一起对外提供服务已经违背了微服务理念。因此,我们有必要对 my-spring-boot 项目进行服务拆分,使它被拆分成一个个小的服务,我们可以安装业务或者功能维度对服务进行拆分,具体如图 16-5 所示。

图 16-5 my-spring-boot 服务拆分

在图 16-5 中,my-spring-boot 项目被拆分为用户服务、角色服务、说说服务等。my-spring-boot 项目依赖于这些底层的服务为其提供相应的功能,而用户服务、角色服务和说说服务是面向接口 API 编程的,符合基本的编程原则。通过服务的拆分和面向接口编程,对于项目扩展和团队分工都有莫大的好处。

16.2.3 服务与接口拆分实践

我们已经清楚服务拆分的原因和好处,本节就要在项目中实践它。首先,我们在 my-spring-boot 项目下添加 ay-user-api、ay-mood-api、ay-role-api 接口模块。具体步骤如下:

步骤 01 选择 my-spring-boot 并右击,在弹出的快捷菜单中单击【New】→【Module】,在弹出的窗口中选择【Spring Initializr】,然后单击【Next】按钮,如图 16-6 所示。

图 16-6 New Module 窗口

步骤 02 在 Name 输入框中输入模块的名称 ay-user-api,其他选项保持默认即可。然后单击【Next】按钮,如图 16-7 所示。

图 16-7 填写模块名称

步骤 03 一路单击【Next】按钮,在 Module name 输入框中填入模块的名称 ay-user-api,然后单击【Finish】按钮,如图 16-8 所示。

图 16-8 填写模块名称

按照上面的步骤就建立好 ay-user-api 模块了。按照相同的步骤,依次在 my-spring-boot 项目下创建接口模块:ay-mood-api 模块、ay-role-api 模块。接口模块创建完成之后,按照相同的步骤创建接口对应的服务模块:ay-user-service 模块、ay-mood-service 模块、ay-role-service 模块。接口模块和对应的服务模块创建完成之后,my-spring-boot 的项目结构如图 16-9 所示。

图 16-9 my-spring-boot 模块目录结构

为了方便,笔者把所有的模块都放在 my-spring-boot 项目下,在真实的项目中并不是这样的。在真实的项目中,我们会为接口和对应的服务单独建立一个项目,比如为 ay-user-api 和 ay-user-service 建立一个项目,为 ay-role-api 和 ay-role-service 建立一个项目,为 ay-mood-api 和 ay-mood-service 建立一个项目。这样不同的开发人员单独负责不同的项目,分工合作,提高开发效率。

所有的模块都建立好之后,我们可以把 my-spring-boot 项目中的接口移动到对应的接口模块。比如把 my-spring-boot 项目中的 AyUserService 接口移动到 ay-user-api,把 AyMoodService 接口移动到 ay-mood-api,等等。同时,把实现类 AyUserServiceImpl 移动到 ay-user-service,把实现类 AyMoodServiceImpl 移动到 ay-mood-service,等等。这里以用户模块为例讲解整个开发过程。

首先,ay-user-api 模块创建完成之后,该模块就是一个 spring-boot 微服务项目,享有 spring-boot 为我们默认生成的各种“福利”。在 ay-user-api 包下创建 api 包和 domain 包,分别用来存放接口类和实体类,在 api 包下存放所有 my-spring-boot 项目移动过来的用户接口。ay-user-api 模块的目录如图 16-10 所示。

图 16-10 ay-user-api 模块目录结构

在图 16-10 中,为了方便,在 api 包下创建 AyUserDubboService 接口,该接口用来提供与用户相关的服务,比如增删改查等功能。AyUserDubboService 类的具体代码如下:

在 AyUserDubboService 类中,只有一个通过用户名和密码查询用户的接口 findByUserNameAndPassword。domain 包下的 AyUser 类具体代码如下:

这里还需要重复强调一遍,api 包下的接口理论上是 my-spring-boot 项目下的用户接口移动过来的,这里选择创建新的接口只是为了方便而已。

16.2.4 正式版发布

ay-user-api 模块接口开发完成之后,我们就可以将其发布成正式版 jar 包。jar 包有快照版 SNAPSHOT 和正式版。比如我们创建的 ay-user-api 模块默认就是快照版 0.0.1-SNAPSHOT。快照版的模块是可以重复修改的,而正式版的模块不可以修改。在开发过程中,模块基本都是 SNAPSHOT 版。当模块开发并测试完成后,会升级为正式版,而且在项目上线的时候,依赖的模块都必须是正式版,否则会出现意想不到的错误。我们可以在 pom 文件中修改模块的版本,比如把 ay-user-api 修改成 0.0.1 正式版,具体步骤如下:

步骤 01 在 ay-user-api 模块中,把 pom 文件 jar 包版本 version 升级为正式版 0.0.1,如图 16-11 所示。

步骤 02 版本修改之后,在 IntelliJ IDEA 开发工具右侧单击【clean】【install】,将 ay-user-api 的 jar 包发布到本地 Maven 仓库,如图 16-12 所示。

图 16-11 修改 pom 文件

图 16-12 clean、install 命令窗口

步骤 03 ay-user-api 正式版的 jar 包发布成功之后,其他项目模块就可以使用它,同时我们可以到 Maven 仓库查看改 jar 包的具体信息,如图 16-13 所示。

图 16-13 ay-user-api 的 Maven 仓库信息

16.2.5 Service 服务端开发

ay-user-api 接口模块发布为正式版之后,继续开发 ay-user-service 模块。首先在 ay-user-service 模块中引入 ay-user-api 的依赖和 Dubbo 依赖。添加 ay-user-api 的依赖是因为 ay-user-service 模块是面向接口编程的,而添加 Dubbo 依赖是因为服务开发完成之后,要把该服务注册到 Zookeeper 中,具体代码如下:

在 ay-user-service 模块中添加完依赖之后,我们开发 AyUserDubboServiceImpl 服务来实现 ay-user-api 中的接口 AyUserDubboService,AyUserDubboServiceImpl 具体代码如下:

  • @Service:这个注解不是 Spring 提供的,而是在 com.alibaba.dubbo.config. annotation.Service 包下面的,这一点要特别注意。在 AyUserDubboServiceImpl 类上添加 @Service 注解就可以把 AyUserDubboServiceImpl 类注册到 Zookeeper 服务中心,对外提供服务。version 属性用于指定服务的版本,这里服务版本为 1.0。当一个接口出现不兼容升级时,可以用版本号 version 过渡,版本号不同的服务相互间不引用。
  • findByUserNameAndPassword 方法:理论上应该在该方法中通过 JPA Repository 或者 MyBatis 查询用户数据,这里为了方便,简单创建 AyUser 对象返回。

16.2.6 Service 服务注册

ay-user-service 模块开发完成之后,由于 ay-user-service 本身是一个 Spring Boot 微服务项目,因此我们可以单独运行它。找到 ay-user-service 模块的入口类 AyUserServiceApplication(确保 Zookeeper 是启动状态),执行入口类的 main 方法便可以启动 ay-user-service 服务。ay-user-service 服务启动完成之后,可以在 IntelliJ IDEA 的控制台中查看服务在 Zookeeper 的注册信息,具体信息如图 16-14 所示。

图 16-14 AyUserDubboService 注册信息

16.2.7 Client 客户端开发

ay-user-api 接口模块和 ay-user-service 服务模块开发完成之后,接下来开始开发客户端。所谓客户端,就是所有 ay-user-service 服务的对象。现在我们把 my-spring-boot 作为客户端,my-spring-boot 本身也是一个微服务。在 my-spring-boot 项目调用 ay-user-service 模块提供的服务,需要在 my-spring-boot 项目的 pom 文件中添加 ay-user-api 依赖和 Dubbo 依赖,具体代码如下:

ay-user-api 依赖和 Dubbo 依赖添加完成之后,我们就可以在代码中通过 @ Reference 注解将 ay-user-service 模块提供的 AyUserDubboService 服务注入进来。具体代码如下:

     @Reference(version = "1.0")
     public AyUserDubboService ayUserDubboService;

@Reference 注解也是 Dubbo 框架提供的,在 com.alibaba.dubbo.config.annotation. Reference 包下。version 是 @Reference 注解的属性,version 的版本需要和 @Service 注解的 version 版本保持一致,否则服务将无法注入,这一点是需要特别注意的。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。