Dubbo+Zookeeper使用
说明:Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。
本文介绍Dubbo的简单使用及一些Dubbo功能特性,注册中心使用的是ZooKeeper,可在官网下载。
(另外,在阿里巴巴发出的《微服务治理技术白皮书》中各种注册中心的区别如下:)

环境搭建
首先,搭建一个ZooKeeper + Dubbo的项目
(1)下载ZooKeeper
在上面提供的官网上下载ZooKeeper,解压到一个没有中文的路径下;

因为默认提供的配置文件是一个模板,解压后需要手动设置一下,将zookeeper默认的配置文件(zoo_sample.cfg)复制一份,并将文件名改为"zoo.cfg"

另外,修改zoo.cfg配置文件中的这行配置,默认的是Linux文件路径,修改为当前目录的上级目录(…/data);

启动,选择安装目录下bin文件夹下的zkServer.cmd文件,可双击启动或者在该目录下打开CMD窗口执行

没有报错,运行结果如下,表示启动成功


如果启动失败,提示此时不应有 jdk,参考:http://t.csdn.cn/52O2K
(2)创建项目
创建一个Zookper+Dubbo的项目,有两个微服务,一个用户服务(UserService),一个订单服务(OrderService),
-
订单服务(消费者,Consumer):没有Service层,直接使用用户服务查询用户信息、用户名;
-
用户服务(提供者,Provider):没有Controller层,提供查询用户信息、用户名的接口;
订单服务(OrderService)
Controlle层,两个接口,一个用于查找用户名,一个用于查找用户。实现暂时空着,待会儿使用Dubbo调用用户服务对应的接口
@RestController
@RequestMapping("order")
public class OrderController {@GetMapping("/name")public String getUserName(Integer id){return userService.getUserName(id);}@GetMapping("/user")public User getUser(Integer id){return userService.getUser(id);}
}
用户服务(UserService)
UserService实现类,实现两个接口,分别是查询用户名,返回固定值;查询用户,返回固定用户对象;
@Service
public class UserServiceImpl implements UserService {@Overridepublic String getUserName(Integer id) {return "getUserName";}@Overridepublic User getUser(Integer id) {User user = new User(30, "张三", "12456");return user;}
}
(3)配置
使用Dubbo前,需先导入依赖,我这里直接在父模块中添加,如下:
<?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.hzy</groupId><artifactId>user-provider</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version><relativePath/></parent><properties><java.version>8</java.version><spring-boot.version>2.2.1.RELEASE</spring-boot.version><dubbo.version>2.7.5</dubbo.version><curator.version>2.12.0</curator.version><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target></properties><dependencies><!--MVC框架--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--dubbo--><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>${dubbo.version}</version></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-dependencies-zookeeper</artifactId><version>${dubbo.version}</version><type>pom</type><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>${curator.version}</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>${curator.version}</version></dependency></dependencies>
</project>
设置各个服务的配置,两方面,一方面是zookeeper,一方面是dubbo的,如下:
(OrderService)
server:port: 8081
spring:application:name: dubbo-consumer
dubbo:registry:address: zookeeper://localhost:2181 # 连接到注册中心protocol:name: dubbo # 指定的协议port: 28081 # 指定的端口scan:basePackages: com.hzy.controller # 接口列表和接口中的方法列表
(UserService)
server:port: 8082
spring:application:name: dubbo-provider
dubbo:registry:address: zookeeper://localhost:2181 # 连接到注册中心protocol:name: dubbo # 指定的协议port: 28082 # 指定的端口scan:basePackages: com.hzy.controller # 接口列表和接口中的方法列表
(4)启动
依次 启动用户服务、订单服务,没有报错说明项目注册到zookeeper没有问题;

打开zookeeper客户端,输入 ls /可查看到dubbo项,再输入ls /dubbo,可查看到注册的服务;

(5)使用
使用Dubbo非常简单,只需如下操作:
- 第一步:修改提供者Service注解,改为Dubbo依赖提供的;

- 第二步:将提供者的UserService接口复制一份到消费者这边来,注意结构要平行相同;

-
第三步:在消费者Controller层注入(引用)UserService接口;
-
第四步:直接调用UserService中的接口;

(6)测试
重启两个服务(注意先启动提供者),使用fastRequest测试;
(获取用户名)

(获取用户信息)

可以看到两个接口都可以正常返回,说明zookeeper+dubbo的结合已完成;
Dubbo特性
以下介绍Dubbo中的一些特性,更多特性用法可在官网中查看;

(1)启动检查
上面一直提到,需要先启动提供者,再启动消费者,这是因为消费者服务依赖于提供者,在启动时Dubbo会进行检查,发现提供者找不到会报错,程序启动失败。

可在消费者这边添加如下配置,取消启动检查
# 取消消费者检查
dubbo:consumer:check: false
再次启动就没有问题了

(2)地址缓存
地址缓存是指,消费者与提供者联系建立起来了,服务消费者会把提供者的接口地址缓存一份,此时注册中心宕机,该请求仍可以正常访问;
发送请求,没得问题;

关闭注册中心zookeeper;

两个服务一直在打印未知错误;

此时,访问刚刚的那个请求,仍然可以成功;

换个重启服务后没发过的请求,也可以访问;

(3)对象传输
使用Dubbo可以传输自定义对象,但需要注意对象需要实现序列号接口,不然会报错;

根据经验,凡是涉及到传输对象,都需要实现序列化接口,并且最好添加全参构造、无参构造,因为有些工具,底层可能是通过对象的全参构造来帮助我们实例化对象的。
(4)连接超时
Dubbo默认设置的连接超时是1秒,即当消费者发送的请求,1秒未得到返回即为超时,这个超时是可以设置的。
在提供者这边方法内设置2秒睡眠;

消费者发送请求,返回超时错误;

连接超时可以在消费者、提供者设置,并且可以在接口、方法上设置,优先级是消费者大于提供者,方法大于接口,如下我在消费者(@Reference)、提供者(@Service)双方设置超时时长;
(消费者,设置1500ms)

(提供者,设置3000ms)

(重启服务,发送请求,依旧报错,说明提供者设置的超时没有起作用,超时是以消费者的1500ms为准)

(互调设置,消费者设置3000ms,提供者1500ms,重启服务可以正常访问)

(5)重试次数
重试次数,在之前连接超时错误的信息,可以看到一个“Tried 3 times”,表示尝试了3次,默认重试2次;

同样,这个也可以在消费者、提供者双方设置
(提供者)
// 设置重试10次
@Service(timeout = 3000, retries = 10)
(消费者)
// 设置重试5次
@Reference(timeout = 1500, retries = 5)
private UserService userService;
同样,优先级是消费者大于提供者;

注意
需要注意哦,不是所有操作都可以设置重试次数的,应该需要考虑当前请求所对应的操作是否为幂等性操作,即执行一次或多次结果都相同,不然会造成数据混乱。以数据库的增删改查操作为例:
-
增:每增加一条数据,数据库表都是变化的,所以为非幂等性;
-
删:与增同理,是非幂等性;
-
改:视情况而定,看SQL语句是怎么写的,如果是"number + 1"这样的,是非幂等性;如果是“set name = #{name} where id = #{id}”这样的,就是幂等性的;
-
查:多次查询(没有其他操作参与)数据库表都是一样的,所以是幂等性操作;
(6)多版本
多版本是指,如果存在多个提供者、消费者时,可以指定版本信息,让提供者指服务指定的消费者,消费者指消费指定的服务者;
(消费者,不指定版本信息)
@Reference(timeout = 3000, retries = 5)
private UserService userService;
(提供者,指定版本信息“V1.0”)
@Service(timeout = 3000, retries = 10, version = "V1.0")
请求失败,提示没有可用的提供者;

修改消费者版本号为“V1.0”;
@Reference(timeout = 3000, retries = 5,version = "V1.0")
请求访问成功;

使用Dubbo的这种特性,可以实现灰度发布,即版本更新不是一下全部更新,而是在系统中设置多个版本,如新版本的接口设置10个,旧版本的接口设置5个,实现“缓更新,慢发布”,减少系统出现异常的风险,比如一些金融、支付类的软件。
(7)负载均衡
可使用“loadbalance”属性设置接口的负载均衡策略,支持以下四种策略:
-
RandomLoadBalance:加权随机,默认算法,默认权重相同;
-
RoundRobinLoadBalance:加权轮询,默认权重相同;
-
LeastActiveLoadBalance:最少活跃优先+加权随机,能者多劳;
-
ConsistentHashLoadBalance:一致性Hash,确定入参,确定提供者,适用于有状态的请求;

注意使用并不是直接new它们类,而是进入到它们对应的类里面,查看它们的这行代码中写的名称

将该名称作为负载均衡属性的值
@Reference(loadbalance = "random")
private UserService userService;
在代码中打印一行标识,开启两个服务,发送十几条请求,可以看到两边服务均有访问,数量不等;


提供者,消费者两边都可以设置,都有效;
(8)失败降级
失败降级是指访问失败时,返回一个降级方案,即“打了折扣”的响应结果,使用mock属性设置,如下:
@Reference(mock = "return 请求错误")
private UserService userService;
另外,还可以有其他几种用法:
# 调用失败,返回请求错误
mock = "return 请求错误"# 不发起远程调用,直接返回null,不管请求成功与否,都返回null
mock = "force:return null"# 发起远程调用,失败后返回null
mock = "fail:return null"# 发起远程调用,失败后抛异常
mock = "throw"# 调用失败后使用自己实现的降级方案
mock = "自定义类的全限定类名"
其中,最后一种方法最好用,搞一下
降级降级方案,实现接口就可以
public class UserServiceMock implements UserService {@Overridepublic String getUserName(Integer id) {return "降级方案";}@Overridepublic User getUser(Integer id) {return new User(-1,"降级对象","降级密码");}
}
mock设置为降级方案的全限定类名
@Reference(mock = "com.hzy.mock.UserServiceMock")private UserService userService;
测试,连接超时,走了降级

(9)集群容错
使用场景(官方);多个服务器部署同一集群中,运行同一应用程序,如果一台服务器出现故障,其他服务器将接管负载,确保应用程序对用户仍然可用。
Failover Cluster(默认设置):失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries=“2” 来设置重试次数(不含第一次)。
其他配置如下:

使用如下:
@Reference(cluster = "failover")
private UserService userService;
同样,也是使用对应的策略,就进入到对应的类中,使用对应的名称作为属性值;

Nacos+Dubbo
Nacos作为注册中心Dubbo使用与ZooKeeper基本相同,在使用上,不同的地方只有以下两点:
-
导入的依赖,配置不同;
-
注解不同,ZooKeeper使用@Service、@Reference注解;Nacos使用@DubboService、@DubboReference注解;
总结
总结成一句话,Dubbo是替代Feign的;
另外提一句,Dubbo是使用自定义的协议,所以如果需要考虑提高Dubbo效率,可以从传输协议、对象序列化方式这些方面入手;
文中代码的GitHub地址:https://github.com/Heapfiy/dubbo-simple.git
相关文章:
Dubbo+Zookeeper使用
说明:Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。 本文介绍Dubbo的简单使用及一些Dubbo功能特性,注册中心使用的是ZooKeeper,可在…...
短视频平台视频怎么去掉水印?
短视频怎么去水印,困扰很多人,例如,有些logo水印,动态水印等等,分享操作经验: 抖音作为中国最受欢迎的社交娱乐应用程序之一,已成为许多人日常生活中不可或缺的一部分。在使用抖音过程中&#x…...
Stable Diffusion - Style Editor 和 Easy Prompt Selector 提示词插件配置
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/132122450 Style Editor 插件: cd extensions git clone https://ghproxy.com/https://github.com/chrisgoringe/Styles-Editor报错&…...
Stable Diffusion - SDXL 模型测试 (DreamShaper 和 GuoFeng v4) 与全身图像参数配置
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/132085757 图像来源于 GuoFeng v4 XL 模型,艺术风格是赛博朋克、漫画、奇幻。 全身图像是指拍摄对象的整个身体都在画面中的照片&…...
中介者模式(Mediator)
中介者模式是一种行为设计模式,可以减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个封装了对象间交互行为的中介者对象来进行合作,从而使对象间耦合松散,并可独立地改变它们之间的交互。中介者…...
SpringBoot使用@Autowired将实现类注入到List或者Map集合中
前言 最近看到RuoYi-Vue-Plus翻译功能 Translation的翻译模块配置类TranslationConfig,其中有一个注入TranslationInterface翻译接口实现类的写法让我感到很新颖,但这种写法在Spring 3.0版本以后就已经支持注入List和Map,平时都没有注意到这…...
【linux目录的权限和粘滞位】
目录: 目录的权限粘滞位总结 目录的权限 可执行权限: 如果目录没有可执行权限, 则无法cd到目录中. 可读权限: 如果目录没有可读权限, 则无法用ls等命令查看目录中的文件内容. 可写权限: 如果目录没有可写权限, 则无法在目录中创建文件, 也无法在目录中删除文件. 粘…...
TP DP PP 并行训练方法介绍
这里写目录标题 张量并行TP流水线并行 PPnaive模型并行GPipePipeDream 数据并行DPFSDP 张量并行TP 挖坑 流水线并行 PP 经典的流水线并行范式有Google推出的Gpipe,和微软推出的PipeDream。两者的推出时间都在2019年左右,大体设计框架一致。主要差别为…...
P005 – Python操作符、操作数和表达式
在Python中,操作符用于对值或变量进行操作。操作数是操作符作用的值或变量。表达式是由操作符、操作数和其他表达式组合而成的,可以求得一个值。 在本文中,我们将探讨Python中的不同类型的操作符,学习如何与操作数一起使用它们来…...
SQL92 SQL99 语法 Oracle 、SQL Server 、MySQL 多表连接、Natural 、USING
SQL92 VS SQL 99 语法 92语法 内连接 from table1, table2 where table1.col table2.col 外连接 放在 从表 左连接: from table1, table2 where table1.col table2.col() 右连接: from table1, table2 where table…...
物联网平台使用笔记
阿里云的IOT平台限制了50个设备。排除 移动云的限制较少,这里试用下。 创建完产品,接入设备后。使用MQTT客户端测试 其中client id 为设备id, username 为产品id, password 可以使用设备调试那里生成的。或使用官方token.exe 生成…...
Python-flask项目入门
一、flask对于简单搭建一个基于python语言-的web项目非常简单 二、项目目录 示例代码 git路径 三、代码介绍 1、安装pip依赖 通过pip插入数据驱动依赖pip install flask-sqlalchemy 和 pip install pymysql 2.配置数据源 config.py DIALECT mysql DRIVER pymysql USERN…...
基于数据库 Sqlite3 的 root 管理系统
1.服务器 1.1服务器函数入口 #include "server.h"int main(int argc, char const *argv[]) {char buf[128] {0};char buf_ID[256] {0};// 接收报错信息判断sqlite3 *db;// 创建员工信息的表格,存在则打开db Sqlite_Create();if (db NULL){printf("sqlite_…...
Hadoop 之 Hive 4.0.0-alpha-2 搭建(八)
Hadoop 之 Hive 搭建与使用 一.Hive 简介二.Hive 搭建1.下载2.安装1.解压并配置 HIVE2.修改 hive-site.xml3.修改 hadoop 的 core-site.xml4.启动 三.Hive 测试1.基础测试2.建库建表3.Java 连接测试1.Pom依赖2.Yarm 配置文件3.启动类4.配置类5.测试类 一.Hive 简介 Hive 是基于…...
vue3常用API之学习笔记
目录 一、setup函数 vue2与vue3变量区别 二、生命周期 三、reactive方法 四、ref方法 1、简介 2、使用 3、ref与reactive 4、获取标签元素或组件 五、toRef 1、简介 2、ref与toRef的区别 六、toRefs 七、shallowReactive 浅reactive 1、简介 2、shallowreactiv…...
Python 程序设计入门(005)—— 字符串操作
Python 程序设计入门(005)—— 字符串操作 目录 Python 程序设计入门(005)—— 字符串操作一、字符串切片与连接1、切片的索引方式2、切片操作的基本表达式3、 切片操作举例4、字符串连接 二、字符串替换:replace() 方…...
怎样将项目jar包放到服务器上
目录 1、在配置文件中配置账号密码 2.在父级的pom里面,加上这个标签 3. deploy部署 4. 注:这两个id得匹配上(原因:有的人会只有上传到测试包的权限,id对应,拥有账号密码的才能有权限) 5.子项…...
ruby调试
如果下载 ruby-debug-ide gem install ruby-debug-ide vscode 下载 ruby扩展 1, ruby 2,修改launch.json...
【云原生】使用kubeadm搭建K8S
目录 一、Kubeadm搭建K8S1.1环境准备1.2所有节点安装docker1.3所有节点安装kubeadm,kubelet和kubectl1.4部署K8S集群1.5所有节点部署网络插件flannel 二、部署 Dashboard 一、Kubeadm搭建K8S 1.1环境准备 服务器IP配置master(2C/4G,cpu核心…...
HCIE-Datacom真题和机构资料
通过认证验证的能力 具备坚实的企业网络跨场景融合解决方案理论知识,能够使用华为数通产品及解决方案进行企业园区网络、广域互联网络及广域承载网络的规划、建设、维护及优化,能够胜任企业网络全场景专家岗位(包括客户经理、项目经理、售前…...
RollBack RX Professional 快照管理避坑指南:锁定、任务属性设置与常见误区解析
RollBack RX Professional 快照管理避坑指南:锁定、任务属性设置与常见误区解析 在系统维护和数据安全领域,快照技术已经成为保障业务连续性的重要手段。RollBack RX Professional作为一款专业的系统还原工具,其快照管理功能在实际应用中展现…...
产品工程师(Product Engineer)角色为何在创业公司成为最稀缺的竞争力?
在科技招聘市场,一位能力顶尖的工程师投递了上百份简历,却始终卡在“技术面试过关、产品讨论却露怯”的阶段。团队明明需要能快速交付价值的人,可最终录用的往往是那些“既懂代码又能自己做产品决策”的少数派。大多数候选人把精力全放在刷 L…...
别再只会拖模块了!用Simulink S-Function把C++算法集成到模型里的保姆级教程
从零实现Simulink与C的深度集成:以PID控制器为例的工程实践指南 在工业自动化和控制系统的开发中,Simulink因其直观的图形化建模能力而广受欢迎。然而,当面对复杂的算法实现或需要复用现有C代码库时,单纯依赖图形化模块往往显得力…...
软考高项案例分析:考点归纳总结
软考高项案例分析:考点归纳总结 结合历年考情来看,目前的考试通常包含3道大题,满分75分,45分及格。 题目构成:通常是 1道计算题(必考)+ 2道理论分析/找茬题。 核心变化:更强调“数据找问题 + 理论给方案”,且可能涉及云计算、AI等数字化场景。 一、计算题(必考,3…...
【网络安全】Web安全防护:从XSS到CSRF的攻防实战
【网络安全】Web安全防护:从XSS到CSRF的攻防实战 引言 Web安全是现代应用开发中不可忽视的重要环节。随着Web应用的普及,各种安全威胁也日益增多。本文将详细介绍常见的Web安全漏洞及其防护方法。 一、XSS攻击与防护 1.1 XSS类型 类型说明攻击方式存储型…...
SD-PPP:打破Photoshop与AI壁垒的革命性插件
SD-PPP:打破Photoshop与AI壁垒的革命性插件 【免费下载链接】sd-ppp A Photoshop AI plugin 项目地址: https://gitcode.com/gh_mirrors/sd/sd-ppp 你是否曾在Photoshop中精心设计到一半,却不得不切换到其他AI工具进行图像生成,然后再…...
别再死记硬背Transformer了!用大白话和代码图解,5分钟搞懂Self-Attention核心
用图书馆借书的故事讲透Transformer自注意力机制 想象你走进一个巨大的图书馆,书架上摆满了各种书籍。你需要找到一本关于"深度学习"的书,但你不确定具体是哪一本。这时候,图书管理员会怎么做?她会根据你的需求…...
哪家网卡公司靠谱必看5大关键清单 企业采购专属版
选网卡公司的3个常见决策误区很多企业采购网卡时踩坑,往往是陷入了三个常见的决策误区。第一个误区是唯价格论,过度压低采购预算,优先选择报价较低的供应商,忽略了产品的授权资质和正品保障,后续容易买到翻新、贴牌的不…...
STM32开发库选型指南:标准库、HAL库与LL库的深度对比与实战应用
1. 项目概述:从寄存器到库,STM32开发的演进之路十年前,当我第一次接触STM32时,面对的是密密麻麻的寄存器手册和几百页的参考手册,一个简单的GPIO点灯操作都需要配置好几个寄存器。那时候,标准库(…...
W5500 TCP客户端开发避坑指南:从寄存器配置到稳定通信的5个关键步骤
W5500 TCP客户端开发避坑指南:从寄存器配置到稳定通信的5个关键步骤 在嵌入式网络通信领域,W5500作为一款硬件集成TCP/IP协议栈的以太网控制器,因其易用性和稳定性备受开发者青睐。然而,当项目从实验室demo转向实际部署时…...
