Dubbo
Dubbo
- 简介
- Dubbo的快速入门
- Dubbo的基本架构
- 安装DubboAdmin
- 入门案例
- Dubbo的最佳实践
- Dubbo的高级特性
- 启动检查
- 多版本
- 超时与重试
- 负载均衡
- SpringCloud整合Dubbo
- 案例
简介
Dubbo是阿里巴巴公司开源的一个高性能、轻量级的Java RPC框架。
致力于提高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案
官网

目前Dubbo在企业中有两种开发思路
- 基于SOA思想
- 将传统单一应用拆分为Web(消费者)模块和Service(提供者)模块,基于Dubbo通信
- 辅助SpringCloud架构提升效率
- Dubbo基于TCP(传输层)协议,效率更高。可以替换Feign,提升高并发压力
Dubbo的快速入门
Dubbo的基本架构

- 服务提供者在启动时,向注册中心注册自己提供的服务
- 消费者在启动时,向注册中心订阅自己所需的服务
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
- 服务消费者,从提供者地址列表中,基于负载均衡算法,选择提供者进行调用。
- 服务消费者和提供者,在内存中累积调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
安装DubboAdmin
DubboAdmin是阿里巴巴管理提供的管理控制台,可以实现服务查询,详细展示,服务测试等功能。皆有DubboAdmin可以更好的帮助开发人员对服务进行管理和监控
DubboAdmin的源代码托管在GitHub上,可以通过命令拉取,修改配置并运行
# 下载代码git clone https://gitcode.net/mirrors/apache/dubbo-admin.git
# 在dubbo-admin-server/src/main/resources/application.properties中指定注册中心
# 构建mvn clean package -D maven.test.skip=true
#启动mvn --projects dubbo-admin-server spring-boot:run
或者cd dubbo-admin-distribution/target; java -jar dubbo-admin-0.1.jar
# 访问http://localhost:8080
# 默认用户名与密码为:root
入门案例
-
创建数据库
CREATE DATABASE `dubbo-demo` ;USE `dubbo-demo`;DROP TABLE IF EXISTS `tb_order`;CREATE TABLE `tb_order` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单id',`userId` bigint(20) NOT NULL COMMENT '用户id',`name` varchar(100) DEFAULT NULL COMMENT '商品名称',`price` bigint(20) NOT NULL COMMENT '商品价格',`num` int(10) DEFAULT '0' COMMENT '商品数量',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `username` (`name`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;insert into `tb_order`(`id`,`userId`,`name`,`price`,`num`) values (101,1,'Apple 苹果 iPhone 12 ',699900,1),(102,2,'雅迪 yadea 新国标电动车',209900,1),(103,3,'骆驼(CAMEL)休闲运动鞋女',43900,1),(104,4,'小米10 双模5G 骁龙865',359900,1),(105,5,'OPPO Reno3 Pro 双模5G 视频双防抖',299900,1),(106,6,'美的(Midea) 新能效 冷静星II ',544900,1),(107,2,'西昊/SIHOO 人体工学电脑椅子',79900,1),(108,3,'梵班(FAMDBANN)休闲男鞋',31900,1);DROP TABLE IF EXISTS `tb_user`;CREATE TABLE `tb_user` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(100) DEFAULT NULL COMMENT '收件人',`address` varchar(255) DEFAULT NULL COMMENT '地址',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `username` (`username`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;insert into `tb_user`(`id`,`username`,`address`) values (1,'柳岩','湖南省衡阳市'),(2,'文二狗','陕西省西安市'),(3,'华沉鱼','湖北省十堰市'),(4,'张必沉','天津市'),(5,'郑爽爽','辽宁省沈阳市大东区'),(6,'范兵兵','山东省青岛市'); -
导入工程
需求:使用Dubbo构建分布构架,完成根据用户id查询用户

搭建服务提供者user-provider
-
创建提供者模块并引入依赖
<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!--dubbo的起步依赖--><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-registry-nacos</artifactId><version>2.7.8</version></dependency> </dependencies> -
编写引导类
package com.xiaowu.user;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@MapperScan("com.xiaowu.user.mapper") @SpringBootApplication public class UserProviderApplication {public static void main( String[] args ) {SpringApplication.run(UserProviderApplication.class,args);} } -
将service,Mapper,domain导入到提供者模块中

-
将UserService暴露为Dubbo服务
//暴露Dubbo服务 @DubboService public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;public User queryById(Long id) {return userMapper.findById(id);} } -
application.yml配置
server:port: 18081 spring:datasource:url: jdbc:mysql://localhost:3306/dubbo-demo?useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverapplication:name: user-provider logging:level:com.xiaowu: debugpattern:dateformat: HH:mm:ss:SSS# 配置Dubbo提供者 dubbo:protocol:name: dubbo # 协议port: 20881 # dubbo端口registry:address: nacos://127.0.0.1:8848 #注册中心地址scan:base-packages: com.xiaowu.user.service # dubbo注解的包扫描
搭建服务消费者user-consumer
-
创建user-consumer模块导入依赖
<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><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>2.7.8</version></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-registry-nacos</artifactId><version>2.7.8</version></dependency> </dependencies> -
将Controller,service接口导入到消费者模块中

-
配置引导类
package com.xiaowu.user;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class UserConsumerApplication {public static void main( String[] args ) {SpringApplication.run(UserConsumerApplication.class,args);} } -
在Controller中引入dubbo服务
@Slf4j @RestController @RequestMapping("/user") public class UserController {@DubboReference //引入dubbo服务private UserService userService;/*** 路径: /user/110* @param id 用户id* @return 用户*/@GetMapping("/{id}")public String queryById( @PathVariable("id") Long id) {return userService.queryById(id);} } -
application.yml配置
server:port: 18080 spring:application:name: user-consumer# 配置dubbo服务消费者 dubbo:registry:address: nacos://127.0.0.1:8848
Dubbo的最佳实践
将API接口抽取为独立模块,并且把接口有关的domain都放到这个模块中


然后引入这个模块的依赖

Dubbo的高级特性
启动检查
为了保障服务的正常可用,Dubbo缺省会启动时检查依赖的服务是否可用,不可用时会抛出异常

- 在正式环境这是很有必要的一项配置,可以保证整个调用链路的平稳运行
- 在开发时,往往会存在没有提供者的情况。由于启动检查的原因,可能导致开发测试出现问题
- 可以通过check=false关闭

多版本
在正式系统中,为了保证系统可用性和更好的并发性,往往通过集群部署

Dubbo提供了提供者多版本的支持,平滑处理项目功能升级部署

具体实现:
-
编写新的UserServer实现类,作为新版本代码
//暴露Dubbo服务 @DubboService(version = "1.0") public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;public User queryById( Long id) {return userMapper.findById(id);} } -
在暴露服务时,指定服务版本
//暴露Dubbo服务 @DubboService(version = "1.0") -
消费者引用服务时,指定引用的服务版本
public class UserController {@DubboReference(version = "1.0") //引入dubbo服务private UserService userService;}
超时与重试
服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩。
- Dubbo:利用超时机制来解决这个问题(使用timeout属性配置超时时间,默认值1000,单位毫秒)
- 若超时时间较短,当网络波动时请求就会失败,Dubbo通过重试机制避免此类问题的发生
设置重试机制的方法
-
在消费者引用Dubbo服务时,加retries参数设置重试机制
@Slf4j @RestController @RequestMapping("/user") public class UserController {@DubboReference(version = "1.0",retries = 0) //引入dubbo服务private UserService userService;/*** 路径: /user/110* @param id 用户id* @return 用户*/@GetMapping("/{id}")public User queryById( @PathVariable("id") Long id) {return userService.queryById(id);} } -
在application.yml配置重试机制
# 配置dubbo服务消费者 dubbo:registry:address: nacos://127.0.0.1:8848consumer:check: falseretries: 0 # 重试机制(0次)
负载均衡
在集群部署时,Dubbo提供了4中负载均衡策略,帮助消费者找到最优提供者并调用
- Random:按权重随机,默认。按权重设置随机概率
- RoundRobin:按权重轮询
- LeastActive:最少活跃调用数,相同活跃数的随机
- ConsistentHash:一致性Hash,相同参数的请求总是发到同一提供者
更改负载均衡策略,在消费者引用Dubbo时加入 loadbalance 参数
@DubboReference(version = "1.0",retries = 0,loadbalance = "Random") //引入dubbo服务
SpringCloud整合Dubbo
- Feign基于Http协议(应用层),在高并发场景下性能不够理想,容易成为性能瓶颈
- Dubbo框架的通信协议采用TCP协议(数据传输层)
- Dubbo框架的通信协议采用RPC协议,属于传输层协议
- Dubbo默认通过Netty构造TCP长连接的方式进行通信,性能较高
- 使用SpringCloud整合Dubbo,即为强强联合
案例
根据订单id查询订单功能
需求:根据订单id查询订单的同时,把订单所属的用户信息一起返回

模块分析
- 使用Dubbo进行服务调用,一般将公共接口独立抽取为模块
- 消费者引入依赖,引用Dubbo服务
- 提供者引入依赖,编写接口实现类,暴露服务

抽取接口模块
-
创建dubbo-api模块,引入依赖
<dependencies><dependency><groupId>com.xiaowu</groupId><artifactId>dubbo-domain</artifactId><version>1.0-SNAPSHOT</version></dependency> </dependencies> -
抽取公共接口

改造提供者
-
引入依赖
<!--nacos注册中心的依赖--> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--springcloud alibaba dubbo依赖 --> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> <!--dubbo-api--> <dependency><groupId>com.xiaowu</groupId><artifactId>dubbo-api</artifactId><version>1.0-SNAPSHOT</version> </dependency> -
编写实现类,暴露Dubbo服务
@DubboService public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;public User queryById(Long id) {return userMapper.findById(id);} } -
application.yml配置
server:port: 8081 spring:datasource:url: jdbc:mysql://localhost:3306/dubbo-demo?useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverapplication:name: user-servicecloud:nacos:discovery:server-addr: localhost:8848 #配置dubbo,注册中心,暴露的端口和协议,dubbo注解的包扫描 dubbo:protocol:name: dubboport: 20881registry:address: spring-cloud://localhost #使用SpringCloud中的注册中心scan:base-packages: com.xiaowu.user.service #dubbo中包扫描 logging:level:com.xiaowu: debugpattern:dateformat: HH-mm ss:SSS
改造服务消费者
-
引入依赖
<!--nacos注册中心的依赖--> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--springcloud alibaba dubbo依赖 --> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> <!--dubbo-api--> <dependency><groupId>com.xiaowu</groupId><artifactId>dubbo-api</artifactId><version>1.0-SNAPSHOT</version> </dependency> -
使用@DubboReference引入Dubbo服务,远程调用服务
@DubboReference private UserService userService; @Autowired private OrderMapper orderMapper; public Order queryOrderById(Long orderId) {// 1.根据id查询订单Order order = orderMapper.findById(orderId);// 2.获取订单中的用户IDLong userId = order.getUserId();// 3.根据用户id,调用Dubbo服务查询用户User user = userService.queryById(userId);order.setUser(user);// 4.返回return order; } -
application.yml进行配置
server:port: 8082 spring:datasource:url: jdbc:mysql://localhost:3306/dubbo-demo?useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Drivercloud:nacos:discovery:server-addr: localhost:8848application:name: order-service# dubbo消费者 dubbo:registry:address: spring-cloud://localhostlogging:level:com.xiaowu: debugpattern:dateformat: HH:mm:ss:SSS
启动测试
- 查询用户

- 查询订单

相关文章:
Dubbo
Dubbo 简介Dubbo的快速入门Dubbo的基本架构安装DubboAdmin入门案例Dubbo的最佳实践 Dubbo的高级特性启动检查多版本超时与重试负载均衡SpringCloud整合Dubbo案例 简介 Dubbo是阿里巴巴公司开源的一个高性能、轻量级的Java RPC框架。 致力于提高性能和透明化的RPC远程服务调用方…...
Java设计模式之策略(Strategy)模式
策略(Strategy)设计模式定义了一系列算法,将它们封装起来,并且可以相互替换使用,从而使得算法可以独立于使用它的客户而变化。 什么是策略模式 策略(Strategy)设计模式是一种行为型设计模式&a…...
Vue引入CDN JS或本地JS文件之后 使用报错
加载问题 正常情况 在public引入script - js文件加载 - 写入内存 - 使用 但使用之前 有可能这个文件还没执行写入内存或者还未加载完毕 此时 需要一个promiss解决 1. 引入script 在 public / index.html 文件内引入你的script标签 <script type"text/javascript"…...
NRF52832-扩展广播
nordic论坛 我想要设置广播名称为 “一二三四五”,当广播名称为FULL_NAME时,但是广播显示还是“一?”,“?”是乱码,后来打开nrf connect观察广播,在没连接的时候,点击一下࿰…...
springboot项目新增子module
1. 拉取项目 2. file-new-module 3. 选择版本 4. 1-2-3-4 5. 注释请求统一前缀 (SwaggerConfig.java)...
Python Web 开发及 Django 总结
title: Python Web 开发及 Django 总结 date: 2023-07-24 17:26:26 tags: PythonWeb categories:Python cover: https://cover.png feature: false Python 基础部分见:Python 基础总结 1. 创建项目 1.1 命令行 1、下载安装 Django 在终端输入 pip install djan…...
《向量数据库指南》:向量数据库Pinecone故障排除
目录 无法pip安装 空闲后索引丢失 上传缓慢或延迟高 批处理带来的高查询延迟 使用gRPC客户端进行Upsert限流 Pods已满 安全问题 CORS错误 本节介绍常见问题以及如何解决它们。需要帮助吗?在我们的支持论坛中提问。标准、企业和专用客户还可以联系支持人员寻求帮助。...
[86] 分割链表
题目链接:86. 分隔链表 - 力扣(LeetCode) 第一种方法:类似双指针 自己想的,不知道读者是否能看懂,参考注释 ListNode* partition(ListNode* head, int x) {ListNode* bigpos nullptr;ListNode* littlep…...
【python】 清空socket缓冲区
在Python中使用Socket进行网络通信时,可以通过调用socket.recv()函数来接收数据,数据会被存储在缓冲区中。有时候,可能想要先清空缓冲区,以便后续的数据不会被之前的数据影响。以下是一种清空Python Socket缓冲区的方法࿱…...
108、RocketMQ的底层实现原理(不需要长篇大论)
RocketMQ的底层实现原理 RocketMQ由NameServer集群、Producer集群、Consumer集群、Broker集群组成,消息生产和消费的大致原理如下: Broker在启动的时候向所有的NameServer注册,并保持长连接,每30s发送一次心跳Producer在发送消息的时候从Na…...
怎么把PDF转为word?1分钟解决难题
PDF文件在我们的电脑上应用非常广泛,由于其较高的安全性和兼容性,得到了广泛的认可。然而,对于一些人来说,PDF文件不能直接进行编辑和修改可能是一个问题。因此,通常我们需要将其转换为Word格式,以便在Word…...
Mysql权限-系统表user,db,talbes_priv,columns_priv详解
一、MySQL 权限场景 可以根据登录用户限制用户访问资源(库、表)可以根据登录用户限制用户的操作权限(能对哪些库、表执行增删改查操作)可以指定用户登录IP或者域名可以限制用户权限分配 二、Mysql五个层级权限级别分析 Mysql权限级别分为了五个层级,并且每个级别…...
GPT-4 模型详细教程
GPT-4(Generative Pretrained Transformer 4)是 OpenAI 的最新语言生成模型,其在各类文本生成任务中表现优秀,深受开发者和研究者喜爱。这篇教程将帮助你理解 GPT-4 的基本概念,并向你展示如何使用它来生成文本。 什么…...
智慧环保:创造绿色未来
随着全球环境问题的日益严重,智慧环保成为推动绿色发展的关键。智慧环保利用先进的技术手段和智能化设备,致力于解决环境问题,保护生态环境,实现可持续发展。它融合了物联网、人工智能、大数据等技术,将科技的力量与环…...
虚拟 DOM和render()函数和Vue.js模板语法
[TOC](虚拟 DOM和render()函数) 1. 虚拟DOM 虚拟DOM是Vue中非常重要的概念,它是一个虚拟的内存中的数据结构,用来表示真实的DOM树。Vue使用虚拟DOM来减少对真实DOM的操作次数,从而提高页面的性能。 虚拟DOM的工作原理如下: Vu…...
k8s Service网络详解(一)
k8s Service网络详解(一) 有关K8s网络的几个概念K8s网络模型k8s网络插件ServiceService的访问方式Service的种类无头服务(Headless Services)带选择算符的服务无选择算符的服务 Service的类型ClusterIPNodeportLoadBalancerExtern…...
抖音账号矩阵系统开发源码
一、技术自研框架开发背景: 抖音账号矩阵系统是一种基于数据分析和管理的全新平台,能够帮助用户更好地管理、扩展和营销抖音账号。 部分源码分享: ic function indexAction() { //面包屑 $breadcrumbs [ [tit…...
Python+Texturepacker自动化处理图片
前言 本篇在讲什么 PythonTexturepacker自动化处理图片 本篇需要什么 对Python语法有简单认知 依赖Python2.7环境 依赖Texturepacker工具 本篇的特色 具有全流程的图文教学 重实践,轻理论,快速上手 提供全流程的源码内容 ★提高阅读体验★ &…...
K8s Service网络详解(二)
K8s Service网络详解(二) Kube Proxy调度模式Kube-proxy IptablesKube-proxy IPVS Service SelectorPod DNS种常见的 DNS 服务Kube-DNSCoreDNSCorefile 配置 DNS 记录DNS 记录 ServiceDNS 记录 PodDNS 配置策略 Pod 的主机名设置优先级 Ingress Kube Pro…...
Rust vs Go:常用语法对比
这个网站 可以列出某门编程语言的常用语法,也可以对比两种语言的基本语法差别。 在此对比Go和Rust 1. Print Hello World 打印Hello World package mainimport "fmt"func main() { fmt.Println("Hello World")} fn main() { println!("…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
