dubbo的springboot集成

news/2025/2/12 15:06:30/

1.什么是dubbo?

        Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。Dubbo 被设计为高度可扩展,用户可以方便的实现流量拦截、选址的各种定制逻辑。

        以上是官方的解释,我个人的理解,dubbo作为一个RPC服务开发框架,除了满足我微服务之间远程调用的目的之外,还能有以下几个重要的点。

        1.和nacos等注册中心,完成dubbo接口服务的服务发现,消费方调用接口无需关注服务端的ip、端口

        2.和sentinel集成,可以完成限流和熔断的目的

        3.dubbo实现了多个负载均衡算法,只需yml文件配置即可。

        4.dubbo和seata可以很方便的集成,轻松达到业务数据一致性的目的。

2.dubbo的常用注解

@EnableDubbo:创建Springboot启动类,需添加@EnableDubbo注解,开启Dubbo自动配置功能

@DubboService:Dubbo会将对应的服务注册到spring, 在spring启动后调用对应的服务导出方法,将服务注册到注册中心, 这样Consumer端才能发现我们发布的服务并调用(与spring的@Service注解作用类似)

@DubboReference:通过@DubboReference注解对需要调用的服务进行引入。即可像调用本地方法一样调用远程服务了。(和spring的@Autowired功能类似)

*注@DubboService@DubboReference的version参数和group参数的值必须一致。这两个参数可以确定一个实现类,接口一般可以有多个实现类的,多个实现类可以通过version和group参数进行区分。

3.代码示例

        示例需要三个工程,一个接口定义、一个服务端,一个消费端。

maven依赖的版本号取决于项目使用的springboot版本及springcloud版本,我使用的版本如下:

<!-- SpringBoot的依赖配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.6.11</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2021.0.1</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2021.0.4.0</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-bom</artifactId><version>3.0.9</version><type>pom</type><scope>import</scope></dependency>

3.1接口示例代码

工程名称:dubbo-demo-interface

实体类必须实现序列化接口,因为在远程调用时,实体类数据是序列化后传输的

package com.jc.shop.dubbo.demo.domain;/*** 用户表*/
public class User implements java.io.Serializable{/*** 主键ID*/private long id;/*** 用户名称*/private String name;/*** 所属部门*/private long deptId;/*** 岗位*/private String post;private Dept dept;public Dept getDept() {return dept;}public void setDept(Dept dept) {this.dept = dept;}public long getId() {return id;}public void setId(long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public long getDeptId() {return deptId;}public void setDeptId(long deptId) {this.deptId = deptId;}public String getPost() {return post;}public void setPost(String post) {this.post = post;}
}

接口定义:

package com.jc.shop.dubbo.demo.service;import com.jc.shop.dubbo.demo.domain.User;/*** 业务接口*/
public interface IUserService {public int insert(User user);
}

3.2服务端示例

服务端工程名:dubbo-demo-provider

 jar包依赖,maven

        <!-- dubbo与spring集成,可实现dubbo的自动初始化 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId></dependency><!-- 实现将dubbo的服务注册到nacos --><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId></dependency><!-- nacos的相关依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- 加载bootstrap.yml文件 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><!-- 引入接口层jar包 --><dependency><groupId>com.jc</groupId><artifactId>dubbo-demo-interface</artifactId><version>1.0-SNAPSHOT</version></dependency>

yml配置

dubbo:application:name: dubbo-providerprotocol:  #dubbo协议信息name: dubbohost: 127.0.0.1port: 20881registry:address: nacos://localhost:8848  #使用nacos作为注册中心

服务层的代码实现:

package com.jc.shop.dubbo.demo.service.impl;import com.jc.shop.dubbo.demo.domain.User;
import com.jc.shop.dubbo.demo.mapper.UserMapper;
import com.jc.shop.dubbo.demo.service.IUserService;
import io.seata.core.context.RootContext;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** 业务层接口,@Service注解不用加,因为我在当前工程的controller中需要调用,所以加了@Service注解*/
@Service
@DubboService(version = "1.0.0",loadbalance = "leastactive")//负载策略为“最少活跃优先 + 加权随机”
public class UserServiceImpl implements IUserService {@Autowiredprivate UserMapper mapper;@Overridepublic int insert(User user) {//以下打印信息是为了集成seata框架的,可忽略,本次不涉及seata框架内容System.out.println("用户新增的事务ID为:"+ RootContext.getXID());return mapper.insert(user);}
}

在当前工程的启动类中,添加@EnableDubbo注解,开启dubbo配置的自动配置功能:

package com.jc;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@EnableDubbo
public class DubboProviderApplication {public static void main(String[] args) {//以下4个变量的设置是为了避免同一台机器,启动多个dubbo服务,缓存默认使用的同一个地址会报错。System.setProperty("dubbo.meta.cache.filePath","/media/zhangzz/localDisk/home/zhangzz/dubbo/provider/");System.setProperty("dubbo.meta.cache.fileName","provider");System.setProperty("dubbo.mapping.cache.filePath","/media/zhangzz/localDisk/home/zhangzz/dubbo/provider/");System.setProperty("dubbo.mapping.cache.fileName","provider1");SpringApplication.run(DubboProviderApplication.class,args);}
}

3.3消费端代码示例

消费端工程名:dubbo-demo-consumer

maven依赖配置:

        <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.2.7</version></dependency><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency>

yml配置:

dubbo:application:name: dubbo-consumerprotocol:  #dubbo协议信息name: dubboport: -1   # -1表示端口随机registry:address: nacos://localhost:8848  #nacos地址

业务层代码调用:

package com.jc.shop.dubbo.demo.service.impl;import com.jc.shop.dubbo.demo.domain.User;
import com.jc.shop.dubbo.demo.service.IConsumerService;
import com.jc.shop.dubbo.demo.service.IUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;@Service
public class ConsumerServiceImpl implements IConsumerService {@DubboReference(version = "1.0.0")  //版本号需和服务端一致,若有group,也需保持一致private IUserService userService;@Overridepublic int insertUser(User user) {int j = userService.insert(user);System.out.println("用户新增,影响行数:"+j);return j;}
}

controller层代码:

package com.jc.shop.dubbo.demo.controller;import com.jc.core.domain.AjaxResult;
import com.jc.shop.dubbo.demo.domain.User;
import com.jc.shop.dubbo.demo.service.IConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/demo")
public class DemoController {@Autowiredprivate IConsumerService service;@PostMapping("/insert")public AjaxResult insert(@RequestBody User user){int i = service.insertUser(user);if(i>0) {return AjaxResult.success("success");}else{return AjaxResult.error();}}
}

应用启动类:

package com.jc;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@EnableDubbo
public class DubboConsumerApplication {public static void main(String[] args) {System.setProperty("dubbo.meta.cache.filePath","/media/zhangzz/localDisk/home/zhangzz/dubbo/consumer/");System.setProperty("dubbo.meta.cache.fileName","consumer");System.setProperty("dubbo.mapping.cache.filePath","/media/zhangzz/localDisk/home/zhangzz/dubbo/consumer/");System.setProperty("dubbo.mapping.cache.fileName","consumer1");SpringApplication.run(DubboConsumerApplication.class,args);}
}

启动之后,访问http://localhost:8082/demo/insert地址

4.与sentinel集成

        集成的配置可参考《sentinel-单机流量控制》或《sentinel-集群流量控制》,此处不再赘述。此处只说明下限流、熔断的资源名称如何定义:

以我的代码为例,规则定义如下:

FlowRule flowRule = new FlowRule(IUserService.class.getName()).setCount(10).setGrade(RuleConstant.FLOW_GRADE_QPS);
FlowRuleManager.loadRules(Collections.singletonList(flowRule));

由以上代码可以看出,资源名称是类的全路径“com.jc.shop.dubbo.demo.service.IUserService”,一般我们的流控规则都是在nacos中配置,由代码动态加载。nacos中的配置如下:

[{"resource":"com.jc.shop.dubbo.demo.service.IUserService", "limitApp":"default",  "grade":1,            "count":1,            "strategy":0,         "controlBehavior":0,  "clusterMode":false}
]

官方文档传送门:dubbo与Sentinel集成的限流示例

5.负载均衡 

目前 Dubbo 内置了如下负载均衡算法,用户可直接配置使用:

算法特性备注配置值
Weighted Random LoadBalance加权随机默认算法,默认权重相同random (默认)
RoundRobin LoadBalance加权轮询借鉴于 Nginx 的平滑加权轮询算法,默认权重相同,roundrobin
LeastActive LoadBalance最少活跃优先 + 加权随机背后是能者多劳的思想leastactive
Shortest-Response LoadBalance最短响应优先 + 加权随机更加关注响应速度shortestresponse
ConsistentHash LoadBalance一致性哈希确定的入参,确定的提供者,适用于有状态请求consistenthash
P2C LoadBalancePower of Two Choice随机选择两个节点后,继续选择“连接数”较小的那个节点。p2c
Adaptive LoadBalance自适应负载均衡在 P2C 算法基础上,选择二者中 load 最小的那个节点adaptive

5.1 使用方式

@DubboService(loadbalance = "leastactive")

@DubboReference(loadbalance = "leastactive")

服务端方法级别的负载配置:

@DubboService(method={@Method(name="insert",loadbalance = "leastactive")})

消费端方法级别的负载配置:

@DubboReference(method={@Method(name="insert",loadbalance = "leastactive")})


http://www.ppmy.cn/news/1299181.html

相关文章

TS 36.306 V12.0.0

​本文的内容主要涉及TS 36.306&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

【服务器数据恢复】Hyper-V虚拟化数据恢复案例

服务器数据恢复环境&#xff1a; Windows Server操作系统服务器&#xff0c;部署Hyper-V虚拟化环境&#xff0c;虚拟机的硬盘文件和配置文件存放在某品牌MD3200存储中&#xff0c;MD3200存储中有一组由4块硬盘组成的raid5阵列&#xff0c;存放虚拟机的数据文件&#xff1b;另外…

阿里云提示服务器ip暴露该怎么办?-速盾网络(sudun)

当阿里云提示服务器IP暴露的时候&#xff0c;这意味着您的服务器可能面临安全风险&#xff0c;因为黑客可以通过知道服务器的IP地址来尝试入侵您的系统。在这种情况下&#xff0c;您应该立即采取措施来保护您的服务器和数据。以下是一些建议&#xff1a; 更改服务器IP地址&…

Vue3 遍历echats图表

1.导入echart import * as echarts from echarts2.主要实现代码 这里使用动态id方法实现遍历 <div v-for"(item,index) in showData" :key"index"><div style"width:100%;height:55%;"><div :id"lineRefindex" style&…

AI真正的Killer App 仍然缺席

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

kettle的基本介绍和使用

1、 kettle概述 1.1 什么是kettle Kettle是一款开源的ETL工具&#xff0c;纯java编写&#xff0c;可以在Window、Linux、Unix上运行&#xff0c;绿色无需安装&#xff0c;数据抽取高效稳定。 1.2 Kettle核心知识点 1.2.1 Kettle工程存储方式 以XML形式存储以资源库方式存储…

RabbitMQ(八)消息的序列化

目录 一、为什么需要消息序列化&#xff1f;二、常用的消息序列化方式1&#xff09;Java原生序列化&#xff08;默认&#xff09;2&#xff09;JSON格式3&#xff09;Protobuf 格式4&#xff09;Avro 格式5&#xff09;MessagePack 格式 三、总结 RabbitMQ 是一个强大的消息中间…

隐藏服务器IP的正确使用方式

简介 IP是英文Internet Protocol的缩写&#xff0c;意思是网络之间互连的协议&#xff0c;也就是为计算机网络相互连接进行通信而设计的协议。在因特网中&#xff0c;它是能使连接到网上的所有计算机网络实现相互通信的一套规则&#xff0c;规定了计算机在因特网上进行通信时应…