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;
|

集群和分布式

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

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

拆分公共服务
RPC

使用注册中心:Nacos、Zookeeper


注解
注册
使用Dubbo包的注解:将这个类提供的方法(服务)对外发布。将访问的地址,端口,路径注册到注册中心中去
@Service public class UserServiceImpl implements UserService {}
|
@DubboService(interfaceClass = IncomeService.class,version = "1.0") public class IncomeServiceImpl implements IncomeService {}
|
拉取
@Reference private UserService userService;
|
@DubboReference(interfaceClass = IncomeService.class,version = "1.0") protected IncomeService incomeService;
|
入门

注册中心 Zookeeper
依赖
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.4.1</version> </dependency>
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.0</version> </dependency>
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.0</version> </dependency>
|
示例

开发中,把控制层和业务层分开部署,所以中间需要用到dubbo远程调用,被调用的远程服务需要注册到注册中心(Zookeeper)中才能被dubbo发现然后调用,
生产者dubbo-service
@Service public class UserServiceImpl implements UserService { @Override public String helloDubbo() { return "Hello!Dubbo!"; } }
|
<dubbo:application name="dubbo-service"/>
<dubbo:registry address="zookeeper://47.115.222.113:2181"/>
<dubbo:annotation package="com.chen.service.impl"/>
|
新版服务提供写法
@DubboService(interfaceClass = IncomeService.class,version = "1.0") public class IncomeServiceImpl implements IncomeService { }
|
配置中心
dubbo: registry: address: zookeeper://localhost:2181 scan: base-packages: com.chen.dataservice.service provider: timeout: 50000 retries: 0
|
消费者 dubbo-web
<dubbo:application name="dubbo-web"/>
<dubbo:registry address="zookeeper://47.115.222.113:2181"/>
<dubbo:annotation package="com.chen.controller"/>
|
@RestController @RequestMapping("/user") public class UserController { @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: registry: address: zookeeper://localhost:2181 scan: base-packages: com.chen.front
consumer: check: false timeout: 50000 retries: 0
|
提供者实现了接口具体的方法,但消费者想要调用,因为是远程,不可以导包,在编写的时候需要写入指定存在的接口,否则无法通过编译,需要指定存在的接口
提供者和消费者都用到了相同接口,所以把通用的接口提取出来放到一个模块,再通过导入jar包来获取模块中要用到的接口,防止接口重复编写
public interface UserService { String helloDubbo(); }
|
admin管理平台

下载
修改地址
进入…\dubbo-admin-develop\dubbo-admin-server\src\main\resources目录,找到 application.properties 配置文件 进行配置修改
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 目录执行清空打包命令
启动
切换目录:dubbo-Admin-develop\dubbo-admin-distribution\target> 找到打包好的jar包
java -jar .\dubbo-admin-0.1.jar
|
dubbo-admin-ui 目录执行命令
访问目标地址,用户名和密码都是 root
<!-- 元数据配置 --> <dubbo:metadata-report address="zookeeper://192.168.149.135:2181" />
|
序列化
提供者和消费者都需要操作对象进行序列化和反序列化 == 》 提取对象在一个专门的模块,使用者导入该模块坐标即可

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

超时与重试


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

例如当前业务有两个版本,迭代升级,一个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;
|
负载均衡

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"/>
|
默认 random
@Reference(loadbalance = "random" )
|
集群容错

@Reference(,cluster = "failover") private UserService userService;
|
服务降级


@Reference(mock = "force:return null") @Reference(mock = "fail:return null") private UserService userService;
|