Dubbo是阿里巴巴公司开源的一个高性能、轻量级的Java RPC框架。
致力于提高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案
官网
目前Dubbo在企业中有两种开发思路
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,'范兵兵','山东省青岛市');
导入工程
搭建服务提供者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);
}
}
将UserService暴露为Dubbo服务
//暴露Dubbo服务
@DubboService
public class UserServiceImpl implements UserService {
@Autowired
private 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=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: user-provider
logging:
level:
com.xiaowu: debug
pattern:
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>
配置引导类
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
将API接口抽取为独立模块,并且把接口有关的domain都放到这个模块中
为了保障服务的正常可用,Dubbo缺省会启动时检查依赖的服务是否可用,不可用时会抛出异常
在正式系统中,为了保证系统可用性和更好的并发性,往往通过集群部署
Dubbo提供了提供者多版本的支持,平滑处理项目功能升级部署
具体实现:
编写新的UserServer实现类,作为新版本代码
//暴露Dubbo服务
@DubboService(version = "1.0")
public class UserServiceImpl implements UserService {
@Autowired
private 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服务时,加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:8848
consumer:
check: false
retries: 0 # 重试机制(0次)
在集群部署时,Dubbo提供了4中负载均衡策略,帮助消费者找到最优提供者并调用
更改负载均衡策略,在消费者引用Dubbo时加入 loadbalance
参数
@DubboReference(version = "1.0",retries = 0,loadbalance = "Random") //引入dubbo服务
根据订单id查询订单功能
需求:根据订单id查询订单的同时,把订单所属的用户信息一起返回
模块分析
抽取接口模块
创建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 {
@Autowired
private 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=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
#配置dubbo,注册中心,暴露的端口和协议,dubbo注解的包扫描
dubbo:
protocol:
name: dubbo
port: 20881
registry:
address: spring-cloud://localhost #使用SpringCloud中的注册中心
scan:
base-packages: com.xiaowu.user.service #dubbo中包扫描
logging:
level:
com.xiaowu: debug
pattern:
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.获取订单中的用户ID
Long 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=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
cloud:
nacos:
discovery:
server-addr: localhost:8848
application:
name: order-service
# dubbo消费者
dubbo:
registry:
address: spring-cloud://localhost
logging:
level:
com.xiaowu: debug
pattern:
dateformat: HH:mm:ss:SSS
启动测试