springboot+dubbo+zookeeper的注册服务和调用实践

devtools/2025/2/27 17:27:31/

目录

    • zookeeper为什么可作为注册中心
    • zookeeper注册中心优缺点
    • 启动zookeeper
    • 编写springboot项目提供dubbo服务
      • 1. 服务接口
      • 2. Springboot引入dubbo实现服务接口
        • 2.1 工程目录和依赖
        • 2.2 启动程序和application.properties
        • 2.3 @DubboService 实现服务接口
        • 2.4 测试api,用于测试启动
    • 开启两个springboot应用
    • dubboAdmin配置随机策略
    • 客户端测试
      • zookeeper客户端查看服务信息
      • zookeeper node metadata字段含义说明
      • 服务提供者2个实例
      • 测试输出和关闭
    • dubbo客户端分析
    • dubbo服务端分析

zookeeper_2">zookeeper为什么可作为注册中心

在这里插入图片描述

zookeeper_5">zookeeper注册中心优缺点

首先需要了解下zookeeper作为注册中心的优缺点
在这里插入图片描述

在这里插入图片描述
结论:尽管ZooKeeper在服务注册与发现、配置管理、分布式锁等场景中非常有用,但它并不适合所有的场景。在选择使用ZooKeeper时,需要根据具体的应用需求、性能要求以及系统的复杂性来综合考虑其优缺点。在一些情况下,可以考虑使用更轻量级的解决方案如Consul或Etcd,这些工具在某些方面可能更适合特定的需求。

zookeeper_13">启动zookeeper

随意启动即可

mubi@mubideMacBook-Pro zookeeper-3.4.12 $ ./bin/zkServer.sh start conf/zoo_local.cfg
ZooKeeper JMX enabled by default
Using config: conf/zoo_local.cfg
Starting zookeeper ... STARTED

dubbo_24">编写springboot项目提供dubbo服务

1. 服务接口

在这里插入图片描述
简单的测试服务接口

package com.example.demoapi.dubboprovider;/*** @Author mubi* @Date 2025/2/21 21:46*/
public interface TestService {int add(int a, int b);
}

依赖

<dependency><groupId>com.dq</groupId><artifactId>spring-groovy-open-service</artifactId><version>1.0-SNAPSHOT</version>
</dependency>

dubbo_53">2. Springboot引入dubbo实现服务接口

2.1 工程目录和依赖

在这里插入图片描述

依赖如下

  • dubbo 2.7.8
  • spring 4.3.18.RELEASE
  • springboot 2.1.4.RELEASE
<?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"><parent><artifactId>spring-groovy-test</artifactId><groupId>com.dq</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>spring-api2</artifactId><dependencies><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.8</version></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId><version>2.7.8</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>2.8.0</version></dependency><!--模块依赖--><dependency><groupId>com.dq</groupId><artifactId>spring-groovy-open-service</artifactId><version>1.0-SNAPSHOT</version></dependency><!--依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency><!-- junit依赖包 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies></project>
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.4.RELEASE</version>
</parent>
2.2 启动程序和application.properties
package com.example.demoapi;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;/*** @Author mubi* @Date 2021/2/13 12:04*/
@EnableDubbo
@SpringBootApplication
@ComponentScan("com.example")
public class DemoApiApplication2 {public static void main(String[] args) {SpringApplication.run(DemoApiApplication2.class, args);}
}
  • application.properties
#https
server.port=8089# Dubbo 配置
dubbo.application.name=demoprovider
dubbo.registry.address=zookeeper://127.0.0.1:2181 
dubbo.protocol.name=dubbo
dubbo.scan.base-packages=com.example.demoapi.dubboprovider
dubbo.protocol.port=20881
2.3 @DubboService 实现服务接口
package com.example.demoapi.dubboprovider;import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;@DubboService
@Service
public class TestServiceImpl implements TestService {@Overridepublic int add(int a, int b) {return a + b + 1;}
}
2.4 测试api,用于测试启动
package com.example.demoapi.control;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @Author mubi* @Date 2021/2/13 12:04*/
@RestController
public class TestControl {@GetMapping(value = "/test")public String getTest() {return "hello test2";}}

在这里插入图片描述

开启两个springboot应用

都提供同样的服务:com.example.demoapi.dubboprovider.TestServicedubbo端口不同

dubbo.protocol.port=20880
dubbo.protocol.port=20881

为了方便测试,可以故意把实现写的不一样

一个是return a + b;
一个是return a + b + 1;

dubboAdmin_250">dubboAdmin配置随机策略

下载一个dubboAmdin.war 然后放到tomcat webapps下启动tomcat即可,如下图
在这里插入图片描述

打开dubbo-admin: http://localhost:8080/dubbo-admin-2.8.4/
在这里插入图片描述
配置一个随机策略,方便测试

在这里插入图片描述

客户端测试

随便起个maven项目
在这里插入图片描述

spring xml配置如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><dubbo:application name="dubbotest" /><dubbo:registry address="zookeeper://127.0.0.1:2181" /><!-- 向注册中心订阅服务 --><dubbo:reference id="testService" interface="com.example.demoapi.dubboprovider.TestService" />
</beans>
  • pom.xml
<?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"><parent><artifactId>dubbo-demo</artifactId><groupId>com.mubi.dubbo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>dubbotest</artifactId><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><!-- spring版本号 --><spring.version>4.3.18.RELEASE</spring.version><!-- log4j日志包版本号 --><slf4j.version>1.7.18</slf4j.version><log4j.version>1.2.17</log4j.version></properties><dependencies><!--模块依赖--><dependency><groupId>com.dq</groupId><artifactId>spring-groovy-open-service</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- spring begin --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-oxm</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><!-- spring end --><!-- 注册中心zookeeper begin --><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.14</version></dependency><!-- 注册中心zookeeper end --><!-- 添加日志相关jar包 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version></dependency><!-- dubbo --><dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><version>2.5.3</version><exclusions><exclusion><groupId>org.springframework</groupId><artifactId>spring</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.101tec</groupId><artifactId>zkclient</artifactId><version>0.10</version></dependency></dependencies></project>
  • 测试
    在这里插入图片描述
    有时候输出4, 有时候输出5,符合预期的负载均衡策略

zookeeper_430">zookeeper客户端查看服务信息

mac使用PrettyZoo可参考文档:https://blog.csdn.net/gitblog_06511/article/details/142393820

可以看到服务如下

在这里插入图片描述

zookeeper_node_metadata_439">zookeeper node metadata字段含义说明

在ZooKeeper中,节点(node)的元数据(metadata)包含了关于该节点的各种信息,这些信息通常通过ZooKeeper的Stat类表示。Stat类包含了多个字段,每个字段都提供了关于节点的不同方面信息。以下是一些常见的Stat类字段及其含义:

  1. czxid - 创建节点的事务ID(Transaction ID)。这是创建该节点时ZooKeeper服务器分配的事务ID。

  2. mzxid - 最后修改节点的事务ID。这是最后一次修改该节点内容或其子节点时ZooKeeper服务器分配的事务ID。

  3. pzxid - 最后修改子节点的事务ID。这是最后一次修改该节点的子节点时ZooKeeper服务器分配的事务ID。

  4. ctime - 创建时间。这是节点被创建的时间戳(以毫秒为单位)。

  5. mtime - 最后修改时间。这是节点最后一次被修改的时间戳(以毫秒为单位),包括内容或子节点的修改。

  6. version - 版本号。每次对节点数据进行修改,版本号会增加。

  7. cversion - 子节点版本号。每次对节点的子节点进行增加、删除操作时,此版本号会增加。

  8. aversion - ACL版本号。每次对节点的ACL(访问控制列表)进行修改时,此版本号会增加。

  9. ephemeralOwner - 临时节点的所有者会话ID。如果是临时节点,则此字段包含创建该临时节点的会话ID;如果是持久节点,则此字段为0。

  10. dataLength - 数据长度。这是存储在节点中的数据部分的长度(以字节为单位)。

  11. numChildren - 子节点数量。这是直接子节点的数量。

  12. pzxid - 最后子节点变更的事务ID(在某些实现中可能不直接暴露,但在某些情况下,特别是在使用某些特定命令或API时可以看到)。

服务提供者2个实例

如下,服务具体提供者(黄色框)是临时结点,其它是持久结点。

  • 测试程序有2个服务提供者
    在这里插入图片描述

测试输出和关闭

  • 测试了三次,且没有关闭测试程序,可以看到三个服务消费者(也是临时结点)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

可以看到有4的输出,也有5的输出


测试进程关闭后,consumer也就没有临时结点了
在这里插入图片描述

dubbo_491">dubbo客户端分析

注意到客户端一直能看到如下日志,即客户端与zookeeper保持了心跳连接

连接在则服务在,consumer临时结点在,否则临时结点消失
在这里插入图片描述

服务的调用当然是dubbo rpc机制。这里暂不具体分析rpc机制,重点看下zookeeper 客户端 SendThread线程(百度AI回答如下)

在这里插入图片描述
所以当我们设计一个客户端的时候,也要考虑心跳维持,队列缓存,异常处理等等问题

dubbo_503">dubbo服务端分析

通过dubbo-admin可以看到服务,并可进行简单的配置负载均衡策略

在这里插入图片描述

在这里插入图片描述

当关闭一个服务提供者之后,同客户端程序,临时结点也是没有了

在这里插入图片描述
在这里插入图片描述

所以服务的动态新增删除,用zookeeper临时结点很方便的表达了


http://www.ppmy.cn/devtools/162761.html

相关文章

【Python 入门基础】—— 人工智能“超级引擎”,AI界的“瑞士军刀”,

欢迎来到ZyyOvO的博客✨&#xff0c;一个关于探索技术的角落&#xff0c;记录学习的点滴&#x1f4d6;&#xff0c;分享实用的技巧&#x1f6e0;️&#xff0c;偶尔还有一些奇思妙想&#x1f4a1; 本文由ZyyOvO原创✍️&#xff0c;感谢支持❤️&#xff01;请尊重原创&#x1…

Go语言中的信号量:原理与实践指南

Go语言中的信号量&#xff1a;原理与实践指南 引言 在并发编程中&#xff0c;控制对共享资源的访问是一个经典问题。Go语言提供了丰富的并发原语&#xff08;如sync.Mutex&#xff09;&#xff0c;但当我们需要灵活限制并发数量时&#xff0c;信号量&#xff08;Semaphore&am…

Linux权限 -- 开发工具

文章目录 包管理器yumyum具体操作 Linux编辑器 - vim的使用vimvim的多模式 包管理器yum Linux中安装软件&#xff1a; 1.源码安装 2. 软件包安装 – rpm 3. 包管理器yum(centos) apt/apt-get(ubuntu) 为什么有包管理器&#xff1f; 包管理器会自动帮我们解决包依赖的问题 2. 什…

OpenCV的形态学操作

在计算机视觉中&#xff0c;形态学操作是一种基于集合论的图像处理技术&#xff0c;主要用于分析和处理图像的形状特征。OpenCV 提供了 cv2.morphologyEx() 函数&#xff0c;用于执行多种高级形态学操作。 kernel np.ones((15, 15), np.uint8) 1. 开运算&#xff08;Opening&…

4-Agent框架重要性、作用是什么?

目录 关键词 全文摘要 章节速览 理解和评估当前的GPT框架 软件开发框架的更新与应用挑战 讨论基础模型在特定领域应用的挑战 科学发展与框架应用在角色交互和API调用中的最佳解决方案 利用框架简化API流程与角色互动 思维导图 发言总结 要点回顾 框架在我们使用现成…

浏览器模块

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1 跨标签页通讯2 浏览器架构3渲染机制3.1 步骤3.2 图层3.3 重绘与回流3.3.1会触发回流的操作有 3.5 缩短白屏时长&#xff0c;可以有以下策略 4 跨域5 浏览器缓存浏…

力扣-动态规划-509 斐波那契数列

思路 dp数组定义&#xff1a;表示下标为i的数列的斐波那契数列值为1递推公式&#xff1a;dp数组初始化&#xff1a;遍历顺序&#xff1a;顺序遍历时间复杂度&#xff1a; 代码 class Solution { public:int fib(int n) {if(n 0) return 0;if(n 1) return 1;vector<int&…

【java基础】Java 中的继承

一、前言 Java 作为一门经典的面向对象编程语言&#xff0c;继承是其核心特性之一。继承就如同家族血脉传承&#xff0c;子类能够承接父类的属性与方法&#xff0c;在复用代码的同时还能按需拓展 二、继承的基本概念 2.1 生活中的继承类比 在日常生活里&#xff0c;继承的概…