Dubbo

Dubbo是 SOA 时代的产物,SpringCloud 是微服务时代的产物

要点

  • 在Dubbo中,服务注册是通过注册接口名称来实现的,而不是实现类名称。Dubbo将服务按照接口名称进行注册和查找,然后根据所选的接口匹配对应的实现类
  • Dubbo的服务提供者会将其服务暴露在注册中心,同时指定提供该服务的接口,而服务消费者则会根据接口名称来引用相应的服务。

使用

  • 生产者:(接口,版本,超时时间,重试次数,服务权重)
@Service(     
interfaceClass = UserService.class,
version = "2.0",
timeout = 3000,
retries = 0,
weight = 100
)
public class UserServiceImpl implements UserService {}

  • 消费者:(接口,版本,负载均衡策略,集群容错,服务降级)
@Reference(
interfaceClass = UserService.class,
version = "2.0",
loadbalance = "random",
cluster = "failover"
,mock = "force:return+null"
)
//新版
@DubboReference()

private UserService userService;


image-20231010143258155





集群和分布式

image-20231010144232055

  1. **集群(Clustering)**:
    • 集群是一组相互连接的计算机或服务器,它们共同工作以提供高可用性和性能。
    • 在Java中,集群通常用于将多个服务器合并成一个单一的逻辑单元,以处理请求并提供故障容忍能力。
    • Java中常用的集群技术包括Java EE(Enterprise Edition)的集群支持,以及第三方集群框架如Apache ZooKeeper和etcd等。
  2. **分布式(Distributed)**:
    • 分布式是指将一个应用程序或系统的不同组件分布在多个计算机或服务器上,这些组件通过网络进行通信和协作。
    • 分布式系统通常用于解决大规模问题,提高性能和可伸缩性,并提供高可用性和容错能力。
    • 在Java中,分布式应用程序通常使用远程方法调用(RMI)、WebSocket、RESTful API等技术来进行跨计算机的通信。
    • Java提供了一些库和框架来简化分布式应用程序的开发,如Java RMI、Spring Boot和Apache Kafka。





架构

  • 单体架构

image-20231010144456998



  • 垂直架构

不关联的拆开,需要的重复写

image-20231010144744866



  • 分布式架构

拆分公共服务

RPC

  • 远程过程调用

image-20231010145057980



  • SOA架构

使用注册中心:Nacos、Zookeeper

image-20231010145253839



  • 微服务架构

image-20231010145515598



注解

注册

  • @Service

使用Dubbo包的注解:将这个类提供的方法(服务)对外发布。将访问的地址,端口,路径注册到注册中心中去

@Service
public class UserServiceImpl implements UserService {}

  • @DubboService

@DubboService(interfaceClass = IncomeService.class,version = "1.0")
public class IncomeServiceImpl implements IncomeService {}


拉取

  • @Reference

@Reference
private UserService userService;


  • @DubboReference

@DubboReference(interfaceClass = IncomeService.class,version = "1.0")
protected IncomeService incomeService;





入门

  • Apache Dubbo

  • Dubbo是阿里巴巴公司开源的一个高性能、轻量级的Java RPC框架。

  • 致力于提供高性能和透明化的RPG远程服务调用方菜,以及SOA服务治理方案

image-20231010150259839



注册中心 Zookeeper



依赖

<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.4.1</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>





示例

image-20231010165639427

开发中,把控制层和业务层分开部署,所以中间需要用到dubbo远程调用,被调用的远程服务需要注册到注册中心(Zookeeper)中才能被dubbo发现然后调用,



生产者dubbo-service

//@Service //将该类的对象创建出来,放到Springe的I0c容器中bean定义

@Service //使用Dubbo的注解:将这个类提供的方法(服务)对外发布。将访问的地址,端口,路径注册到注册中心中
public class UserServiceImpl implements UserService {
@Override
public String helloDubbo() {
return "Hello!Dubbo!";
}
}
<!--dubbo配置-->
<!--1.配置项目名称,唯一 -->
<dubbo:application name="dubbo-service"/>
<!--2.配置注册中心地址 -->
<dubbo:registry address="zookeeper://47.115.222.113:2181"/>
<!--3.配置dubbo包扫描-->
<dubbo:annotation package="com.chen.service.impl"/>

新版服务提供写法

// 标明接口
@DubboService(interfaceClass = IncomeService.class,version = "1.0")
public class IncomeServiceImpl implements IncomeService {
}

配置中心

#dubbo基本配置
dubbo:
registry:
address: zookeeper://localhost:2181 #注册中心
scan:
base-packages: com.chen.dataservice.service
provider: #提供者
timeout: 50000
retries: 0


消费者 dubbo-web

<!--dubbo配置-->
<!--1.配置项目名称,唯一 -->
<dubbo:application name="dubbo-web"/>
<!--2.配置注册中心地址 -->
<dubbo:registry address="zookeeper://47.115.222.113:2181"/>
<!--3.配置dubbo包扫描-->
<dubbo:annotation package="com.chen.controller"/>
@RestController
@RequestMapping("/user")
public class UserController {

//使用Reference获取服务
@Reference
private UserService userService;

@RequestMapping("/hello.do")
public String sayHello(){
return userService.helloDubbo();
}

}

Dubbo新版本写法

// 标明接口
@DubboReference(interfaceClass = IncomeService.class,version = "1.0")
protected IncomeService incomeService;

配置中心–消费者

#dubbo的注册服务
dubbo:
registry:
address: zookeeper://localhost:2181
scan:
base-packages: com.chen.front

consumer:
check: false
timeout: 50000
retries: 0


  • 共同接口 dubbo-api

提供者实现了接口具体的方法,但消费者想要调用,因为是远程,不可以导包,在编写的时候需要写入指定存在的接口,否则无法通过编译,需要指定存在的接口

提供者和消费者都用到了相同接口,所以把通用的接口提取出来放到一个模块,再通过导入jar包来获取模块中要用到的接口,防止接口重复编写

public interface UserService {
String helloDubbo();
}





admin管理平台

image-20231010184246225



下载



修改地址

进入…\dubbo-admin-develop\dubbo-admin-server\src\main\resources目录,找到 application.properties 配置文件 进行配置修改

  • 修改zookeeper地址
# centers in dubbo2.7
admin.registry.address=zookeeper://47.115.222.113:2181
admin.config-center=zookeeper://47.115.222.113:2181
admin.metadata-report.address=zookeeper://47.115.222.113:2181



打包项目

CMD 在 dubbo-admin-develop 目录执行清空打包命令

mvn clean package


启动

切换目录:dubbo-Admin-develop\dubbo-admin-distribution\target> 找到打包好的jar包

java -jar .\dubbo-admin-0.1.jar


dubbo-admin-ui 目录执行命令

npm run dev


访问目标地址,用户名和密码都是 root



<!-- 元数据配置 -->
<dubbo:metadata-report address="zookeeper://192.168.149.135:2181" />





序列化

提供者和消费者都需要操作对象进行序列化和反序列化 == 》 提取对象在一个专门的模块,使用者导入该模块坐标即可

image-20231010210526096

  • 对象传输需要序列化,Dubbo已经集成自动序列化传输和反序列化,只需要在对象类上实现序列化接口
public class User implements Serializable {}





地址缓存

image-20231010215219905






超时与重试

image-20231010215521609

image-20231010221107127


  • 建议服务提供者设置超时与重试
@Service(timeout = 3000,retries = 0) //超时时间,重试次数

  • 调用远程也可以设置超时时间,超时时间短过提供者的话会覆盖服务提供者设置的超时时间
@Reference(timeout = 3000)
private UserService userService;





多版本

image-20231010221433735



  • 提供者设置当前版本

例如当前业务有两个版本,迭代升级,一个1.0,一个2.0

@Service(version = "1.0")
public class UserServiceImpl implements UserService {}
@Service(version = "2.0")
public class UserServiceImpl2 implements UserService {}


  • 消费者自行选择版本进行根据接口进行选择实现类服务调用

当存在多版本,必须标明版本调用

@Reference(version = "2.0")
private UserService userService;





负载均衡

image-20231010224205476



  • 伪集群添加配置,防止端口冲突

protocol:服务提供者将在端口号 20882 上监听来自消费者的请求。这是一个必需的属性,如果不指定端口号,Dubbo将使用默认的端口 20880

qos.port:QoS服务的端口号。QoS服务可以用于监控Dubbo服务的性能、负载和其他指标,并提供相关的统计信息。

<!--dubbo配置-->
<dubbo:protocol port="20882"/>
<!--1.配置项目名称,唯一 -->
<dubbo:application name="dubbo-service">
<dubbo:parameter key="qos.port" value="2222"/>
</dubbo:application>
<!--2.配置注册中心地址 -->
<dubbo:registry address="zookeeper://47.115.222.113:2181"/>
<!--3.配置dubbo包扫描-->
<dubbo:annotation package="com.chen.service.impl"/>


  • 服务设置权重
@Service(weight = 100)

  • 消费者选择策略 – loadbalance

默认 random

@Reference(loadbalance = "random" )





集群容错

image-20231010233512295



  • 在消费者处配置
@Reference(,cluster = "failover")
private UserService userService;





服务降级

image-20231010235016555

image-20231010234724169

  • 消费者配置
@Reference(mock = "force:return null") //不发起调用
@Reference(mock = "fail:return null") //失败返回null
private UserService userService;