当前位置: 首页 > news >正文

如何将Dubbo从Zookeeper平滑地迁移到Nacos?

在这篇文章中 zookeeper命令入门 我们学习了zookeeper的相关命令。如果大家不知道zookeeper的命令,推荐去阅读一下这篇文章,对后面的理解有帮助。

文章目录

    • zookeeper存的是什么样的数据
      • 启动生产者
      • 启动消费者
      • 同时启动
    • Dubbo集成Nacos
      • Nacos 版本映射关系
      • 搭建环境
      • 第一步,搭建最少3个maven模块
      • 第二步,编写pom文件
      • 第三步,编写生产者和消费者
      • 第四步,编写配置文件
      • 第五步,启动消费者和生产者

在dubbo官方,推荐使用Zookeeper作为注册中心。然后我们就使用Springboot加Dubbo进行了实战练习 如何使用Dubbo进行优雅的开发? 如果大家不知道怎么Springboot集成Dubbo,推荐大家先去看了这篇文章。

但是现在随着nacos也能集成Dubbo,使用zookeeper的越来越少了,很多公司也在把注册中心往nacos方面迁移。所以我们这次来讲如何使用Nacos集成Dubbo应用。

使用 Nacos 集成 Dubbo的优点:

  1. 更全面的服务治理功能:Nacos 不仅支持服务注册与发现,还提供了动态配置管理、服务健康检查等功能,有助于简化服务治理。
  2. 简单易用:Nacos 的界面友好,易于操作,对于开发者来说更加直观和便捷。
  3. 高可用性:Nacos 支持集群部署模式,能够提供更高的可用性和稳定性。
  4. 兼容多种协议和服务发现机制:除了 Dubbo,Nacos 还支持其他协议(如 gRPC、HTTP 等)和服务发现机制,增加了灵活性。
  5. 用户友好的界面:Zookeeper 自带的界面不够直观,通常需要额外的工具来增强用户体验。Nacos自带有界面

由于在上一篇文章中我们讲了Springboot集成Dubbo,所以如果大家不知道怎么搭建项目环境的可以去查看上一篇文章 如何使用Dubbo进行优雅的开发? ,首先来看下面讲的案例,注册中心是zookeeper。相比于上篇文章,我们改了一下模块架构。仓库地址 dubbo+zookeeper

zookeeper存的是什么样的数据

那么我们在讲如何使用Nacos集成Dubbo应用之前,我们需要看一下原来的zookeeper里面是怎么存Dubbo的服务的,即Dubbo的rpc接口在zk里面长什么样?

我们在没启动Dubbo服务之前来看一下zookeeper 的znode节点里面有什么东西:

image-20250112103850077

可以看到的是根部有个zookeeper节点,里面是没有东西的

启动生产者

那么这个时候我们在本地启动一个Dubbo的生产者服务看看:rpc生产者服务

image-20250112104115473

启动之后我们再去看看zookeeper的znode节点会发生什么变化:

image-20250112104303604

我们可以看到里面的结构长这样:

image-20250112104604389

/dubbo/{service_name}/configurators 路径下的数据通常用于存放针对特定服务的动态配置信息。这些配置可以是:

  1. 权重调整:可以为不同的服务提供者设置不同的权重值,以便控制流量分配。
  2. 路由规则:定义哪些请求应该路由到哪些服务提供者上,可以基于某些条件来过滤服务提供者。
  3. 其他参数调整:比如连接超时时间、重试次数等。

如果我们把这个node删掉,rpc服务会立马报错

org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /dubbo/com.masiyi.service.UserService/configuratorsat org.apache.zookeeper.KeeperException.create(KeeperException.java:111) ~[zookeeper-3.4.9.jar:3.4.9-1757313]at org.apache.zookeeper.KeeperException.create(KeeperException.java:51) ~[zookeeper-3.4.9.jar:3.4.9-1757313]

而我们的整体znode大概就是这样的:

/                        --> 根节点
│
├── dubbo                 --> 存储Dubbo服务信息的根节点
│   └── com.masiyi.service.UserService  --> 特定服务的ZNode
│       ├── configurators  --> 配置提供者
│       │   └── 172.19.48.1    --> 配置提供者的IP地址
│       │
│       └── providers      --> 提供者列表
│           └── dubbo://172.19.48.1:20881/com.masiyi.service.UserService?anyhost=true&application=rpc-server&dubbo=2.6.2&generic=false&interface=com.masiyi.service.UserService&methods=queryUser&pid=26136&side=provider&timestamp=1736649664500
│               └── 172.19.48.1 --> 服务提供者的IP地址

我们可以看到 providers znode(每当有一个服务提供者启动并成功注册到Dubbo注册中心时,相关信息就会被写入到这里。这样,当有服务消费方需要调用该服务时,就可以从这里获取服务提供者的地址和端口等信息。)提供者列表里面存的数据为:

 com.masiyi.service.UserService - Application: rpc-server       - Interface: com.masiyi.service.UserService                  - Methods: queryUser            - Protocol: dubbo              - Host: 172.19.48.1            - Port: 20881                  - Side: provider                - Timestamp: 1736649664500      

而我们在生产者的代码里面添加一个方法 queryUser2 就会变成这样:

dubbo://172.19.48.1:20881/com.masiyi.service.UserService?anyhost=true&application=rpc-server&dubbo=2.6.2&generic=false&interface=com.masiyi.service.UserService&methods=queryUser2,queryUser&pid=32500&side=provider&timestamp=1736651113593

最后的ZNode里面的数据如下:
znode

那么生产者这里我们可以看出什么东西来呢?每一个service都会在 /dubbo这个下面有一个对应的znode,这个znode命名就是这个类的全限定类名,在这个znode下面的 providersznode,里面存着生产者的具体信息。

那么有了这个我们就可以通过接口调用工具去调用这个rpc接口进行调试了,例如这样:

image-20250112140906086

启动消费者

我们可以单独启动我们的消费者看一下,zookeeper里面的数据会发生变化吗?web消费者服务

image-20250112172322669
在这里插入图片描述

可以看到,这次相对于单启动生产者多了个consumersrouters节点,而这个consumers节点则记录着被 @Reference注解修饰着的生产者类:(check = false 属性可以让消费者先启动的情况下不报错)每个Dubbo服务消费者在启动时会在此目录下创建一个节点,以表示它对服务的关注和使用情况。

package com.masiyi.controller;import com.alibaba.dubbo.config.annotation.Reference;
import com.masiyi.entity.Role;
import com.masiyi.entity.User;
import com.masiyi.service.RoleService;
import com.masiyi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@Autowiredprivate UserService userService;@Reference(check = false)private RoleService roleService;@GetMapping("/user")public User user() {User user = userService.queryUser();Role role = roleService.role();user.setRole(role);return user;}
}

同时启动

我们把生产者和消费者一起启动起来看看里面的znode会变成什么样

image-20250112174207714

这四个子znode共同构成了Apache Dubbo框架中服务治理的基础架构:

  • Configurators用于动态配置管理,使得无需重启即可调整服务行为。
  • Consumers追踪所有服务消费者的信息,有助于服务调用关系的管理和监控。
  • Providers记录所有服务提供者的详情,是服务发现机制的核心部分。
  • Routers通过设定路由规则来控制请求的流向,支持复杂的服务治理需求

而我们看到Consumers 和 Providers 里面都有着对应的数据,也就是说现在这个类 com.masiyi.service.RoleService既有消费者又有生产者。那么我自然就可以进行正常的调用了:
image-20250112174930786

ohhh,现在终于知道了zookeeper里面的数据长什么样了。那么我现在开始说正事:Dubbo集成Nacos。

Dubbo集成Nacos

前面我们说了那么多好像都没有什么关系,可能有小伙伴疑惑了。别急,我们先来看一个事情,小学二年级我们学过,一般我们都是用feign去将一个服务注册为一个生产者,如果我们的系统有很多的模块,每个模块对应一个微服务,那么我们在nacos上面则会看到这样的服务列表:

在这里插入图片描述

即每个微服务(可以理解为一个运行的jar包)都是对应一条数据,但是Dubbo不一样,就拿我们上面的例子,每个生产者提供的类就是一个对应的服务,很好理解,就是zookeeper里面对应的每个节点,就像这样:

image-20250112202532258

Nacos 版本映射关系

Dubbo推荐 Nacos 版本Nacos 兼容范围
3.3.02.3.02.x
3.2.212.1.02.x
3.1.112.0.92.x
3.0.102.0.92.x
2.7.211.x最新版本1.x
2.6.01.x最新版本1.x

作者演示的环境nacos版本是2.2.0,Dubbo版本是3.3.0,JDK是1.8

搭建环境

第一步,搭建最少3个maven模块

作者这边搭建了4个maven模块,他们之间的关系是这样的

注册中心的主要职责是服务的注册与发现,它提供了一个中心化的视图,使得服务消费者能够找到并连接到适当的服务提供者。

  • 服务注册:当一个服务启动时,它会将自己的地址(如IP地址和端口号)、版本号等信息注册到注册中心。
  • 服务发现:服务消费者在需要调用其他服务时,会向注册中心查询所需服务的地址列表。基于某种策略(例如随机、轮询或根据负载情况),消费者选择一个合适的服务提供者进行直接通信。
  • 健康检查:注册中心还负责对已注册的服务进行健康检查。如果某个服务实例不可用了,注册中心会更新其状态,从而避免将请求路由到不健康的实例上。

image-20250112204525726

第二步,编写pom文件

web-server

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.masiyi</groupId><artifactId>web-server</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.masiyi</groupId><artifactId>service</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-nacos-spring-boot-starter</artifactId><version>3.3.0</version></dependency></dependencies></project>

server

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.masiyi</groupId><artifactId>service</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.12</version></dependency><dependency><groupId>com.masiyi</groupId><artifactId>api</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
</project>

rpc-server

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.masiyi</groupId><artifactId>rpc-server</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-nacos-spring-boot-starter</artifactId><version>3.3.0</version></dependency><dependency><groupId>com.masiyi</groupId><artifactId>api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency></dependencies></project>

api

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.masiyi</groupId><artifactId>api</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties></project>

第三步,编写生产者和消费者

具体的代码请查看代码仓库 : dubbo-nacos

注意这里使用@EnableDubboConfig,@DubboComponentScan注解代替了老版本的 EnableDubbo,使用 @DubboService代替了老版本的 Service, @DubboReference代替了 Reference

第四步,编写配置文件

生产者(rpc-server)

spring.application.name=rpc-serverserver.port=8082dubbo.application.name=rpc-server
dubbo.registry.address=nacos://localhost:8848dubbo.protocol.name=dubbo
dubbo.protocol.port=20881

消费者(web-server)

spring.application.name=web-server
server.port=8083dubbo.application.name=web-server
dubbo.registry.address=nacos://localhost:8848dubbo.protocol.port=20885

第五步,启动消费者和生产者

启动完成之后就可以在nacos看到这些消息了

image-20250112205802966

image-20250112205841420

image-20250112205901208

上面的基本页面是没问题的,我们再来看一下每个服务具体的详情页面:

image-20250112210040292

可以看到,这里面的详情信息就是之前我们在zookeeper里面providers znode看到的消息是一样的。那么我们也可以调用一下接口看看效果也是没问题的:

image-20250112210215427

至此,我们的Dubbo集成Nacos就完成了,随着我们将Dubbo成功集成到Nacos中,这一过程不仅标志着技术上的里程碑,也象征着Dubbo“回归娘家”的历程。Dubbo最初由阿里巴巴开源,并于2011年作为一款高性能的Java RPC框架公开发布。它迅速成为了构建分布式服务架构的首选之一。

在2017年,Dubbo被捐赠给Apache软件基金会(Apache Software Foundation),并在2019年正式毕业成为Apache顶级项目(Top-Level Project)。这一过程不仅是对Dubbo技术实力的认可,更是对其社区活跃度和开放性的一种肯定。在Apache基金会的支持下,Dubbo得到了全球范围内更多的开发者和企业的关注与贡献,进一步推动了其发展和创新。

尽管Dubbo曾一度淡出公众视野,但它始终保持着强劲的生命力,这得益于其开放源代码的本质和活跃的社区支持。阿里巴巴重新重视并投入资源继续发展Dubbo,将其视为其云原生战略的关键部分,进一步巩固了Dubbo在现代分布式系统中的地位。

谢谢大家观看。

http://www.dtcms.com/a/319202.html

相关文章:

  • 38.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--增加日志记录器
  • Android视图状态以及重绘
  • Java面试宝典:类加载
  • 利用vue.js2X写前端搜索页面,express写后端API接口展现搜索数据
  • SymPy 中 atan2(y, x)函数的深度解析
  • vue3对比vue2的性能优化和提升 :Vue 3 vs Vue 2
  • ArkTS: McPointChart
  • 【Redis面试精讲 Day 16】Redis性能监控与分析工具
  • 从Web2.0到Web3.0——用户体验如何演进
  • 树莓派安装中文输入法
  • Day09 Tlisa登录认证
  • Linux总线,设备和驱动关系以及匹配机制解析
  • FPGA学习笔记——VGA显示静态图片(ROM IP核)
  • 【博弈 拓扑序 缩点】P9220 「TAOI-1」椎名真昼|省选-
  • Bosco-and-Mancuso Filter for CFA Image Denoising
  • 如何快速掌握Excel公式?14天轻松通关
  • LeetCode 面试经典 150_数组/字符串_除自身以外数组的乘积(13_238_C++_中等)(前缀积)
  • Swift 实战:高效设计 Tic-Tac-Toe 游戏逻辑(LeetCode 348)
  • 解决chrome下载crx文件被自动删除,加载未打包的扩展程序时提示“无法安装扩展程序,因为它使用了不受支持的清单版本解决方案”
  • 冷库温湿度物联网监控系统解决方案:冷链智能化
  • 普通冷库如何升级物联网冷库?工业智能网关赋能冷链智能化转型
  • AI摄像机如何为煤矿减少90%违规事故?
  • HarmonyOS 页面跳转新方案:HMRouter 路由框架全方位使用指南与实践案例
  • Axure 高阶设计:打造“以假乱真”的多图片上传组件
  • 如何使用vLLM运行gpt-oss
  • Nodejs》》MySql
  • 单链表专题---暴力算法美学(1)(有视频演示)
  • Keil MDK-ARM V5.42a 完整安装教程
  • 如何使用Ollama在本地运行gpt-oss
  • 09-netty基础-手写rpc-原理-01