Dubbo是阿里巴巴公司开源的一个高性能、轻量级的 Java RPC 框架。
致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。
官网:http://dubbo.apache.org
目前Dubbo在企业中有两种开发思路
- 基于SOA思想
将传统单一应用拆分为web(消费者)模块和service(提供者)模块,基于Dubbo通信。
- 辅助SpringCloud架构提升效率
Dubbo基于TCP(传输层)协议,效率更高。可以替换Feign,提升高并发压力。
Dubbo入门
Dubbo的基本架构
服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者在启动时,向注册中心订阅自己所需的服务。
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于负载均衡算法,选择提供者进行调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
入门实践
1、安装Nacos(参考nocos章节)
2、安装DubboAdmin
DubboAdmin是阿里巴巴管理提供的管理控制台,可以实现服务查询,详情展示,服务测试等功能。借由DubboAdmin可以更好的帮助开发人员对服务进行管理和监控。
DubboAdmin的源代码托管在github上,可以通过命令拉取。修改配置并运行
1、下载代码: git clone https://github.com/apache/dubbo-admin.git 2、在 dubbo-admin-server/src/main/resources/application.properties中指定注册中心地址 3、构建 mvn clean package -Dmaven.test.skip=true 4、启动mvn --projects dubbo-admin-server spring-boot:run或者cd dubbo-admin-distribution/target; java -jar dubbo-admin-0.1.jar 5、访问 http://localhost:8080
3、使用Dubbo构建分布式架构,完成根据用户id查询用户
3.1 搭建服务提供者user-provider
1、创建提供者模块并引入依赖(pom.xml)
<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>
2、将service,mapper,domain导入到提供者模块中
3、将UserSerivice暴露为dubbo服务
@DubboService public class UserServiceImpl implements UserService {………… }
4、application.yml配置
server:port: 18081
spring:datasource:url: jdbc:mysql://localhost:3306/dubbo-demo?useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driverapplication:name: user-provider
logging:level:cn.itcast: debugpattern:dateformat: HH:mm:ss:SSS
# 配置dubbo提供者
# dubbo协议和访问端口
dubbo:protocol:name: dubboport: 20881
# 注册中心的地址registry:address: nacos://127.0.0.1:8848
# dubbo注解的包扫描scan:base-packages: cn.itcast.user.service
注:针对dubbo协议及访问端口:服务消费者调用Netty服务器的20881端口,Netty相当于Socket服务器。Tomcat相当于提供者运行启动的容器。
3.2 搭建服务消费者user-consumer
1、创建提供者模块并引入依赖
<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>
2、将controller,service接口导入到提供者模块中
3、在Controller中引入dubbo服务
@RestController @RequestMapping("/user") public class UserController {//引用远程服务 @DubboReferenceprivate UserService userService;
4、application.yml配置
server:port: 18080
spring:application:name: user-consumer
logging:level:cn.itcast: debugpattern:dateformat: HH:mm:ss:SSS
dubbo:registry:address: nacos://127.0.0.1:8848
3.3 将API接口抽取为独立模块,并且把接口有关的domain都放到这个模块中
序列化
两个机器传输数据,在RPC通信时,往往采用二进制数据格式传输Java对象,故需要对对象进行序列化处理。
dubbo 内部已经将序列化和反序列化的过程内部封装了。在定义domain类时实现Serializable接口即可。
Dubbo的高级特性
启动检查
为了保障服务的正常可用,Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常。
在正式环境这是很有必要的一项配置,可以保证整个调用链路的平稳运行。
在开发时,往往会存在没有提供者的情况。由于启动检查的原因,可能导致开发测试出现问题。
可以通过check=false关闭。
多版本
在正式系统中,为了保证系统可用性和更好的并发性,往往通过集群部署。
如果提供者代码出现重大更新。如何对提供者升级部署呢?
Dubbo提供了提供者多版本的支持,平滑处理项目功能升级部署。
灰度发布:当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能。
多版本实现
1、编写新的UserServce实现类,作为新版本代码2、在暴露服务时,指定服务版本
3、消费者引用服务时,指定引用的服务版本
超时与重试
服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩。
- dubbo 利用超时机制来解决这个问题(使用timeout属性配置超时时间,默认值1000,单位毫秒)。
消费者调用提供者是设置一个超时时间,等待超过该时间无响应将连接关闭。
- 若超时时间较短,当网络波动时请求就会失败,Dubbo通过重试机制避免此类问题的发生。
针对增删改涉及数据库数据情况,重试三次会导致数据出错
1、可通过@DubboReference 的retries=0关闭重试:
2、也可以修改application.yml关闭所有消费者重试
负载均衡
在集群部署时,Dubbo提供了4种负载均衡策略,帮助消费者找到最优提供者并调用
- Random :按权重随机,默认值。按权重设置随机概率。
- RoundRobin :按权重轮询
- LeastActive:最少活跃调用数,相同活跃数的随机。
- ConsistentHash:一致性 Hash,相同参数的请求总是发到同一提供者。
可通过@DubboReference 的loadbalance进行设置。