文章目录
- 一、概述
- 二、Dubbo环境搭建-docker版
- 三、Dubbo配置
- 四、高可用
- 4.1 zookeeper宕机与dubbo直连
- 4.2 负载均衡
- 五、服务限流、服务降级、服务容错
- 六、Dubbo 对比 OpenFeign
一、概述
Dubbo 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。对标Spring Cloud 中的 OpenFeign但功能更丰富,含限流、降级、熔断,另外可搭配 Hystrix 使用。一般搭配注册中心 ZooKeeper 使用。Dubbo底层通信使用的是netty。介于目前Dubbo发展及使用情况,本章内容仅蜻蜓点水般介绍Dubbo及使用,并不深入研究,如需深入学习,请参考官网。
官网:http://dubbo.apache.org/
服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
二、Dubbo环境搭建-docker版
- 注册中心 ZooKeeper,docker启动:
docker run zookeeper
- 编写 dubbo-admin配置文件
application.properties
,后续需使用,本人放在/root/dockerData/dubbo/dubbo-admin/properties
目录
in.registry.address=zookeeper://192.168.115.129:2181
admin.config-center=zookeeper://192.168.115.129:2181
admin.root.user.name=root
admin.root.user.password=root
admin.check.signSecret=86295dd0c4ef69a1036b0b0c15158d77
- 启动 dubbo-admin:
docker run -itd --net=host --name dubbo-admin -v /root/dockerData/dubbo/dubbo-admin/properties:/config apache/dubbo-admin
。官网:https://github.com/apache/dubbo-admin - 参考官网搭建 dubbo 示例项目:https://cn.dubbo.apache.org/zh-cn/overview/quickstart/java/spring-boot/ ,动手实践(从零代码开发版)
这里提供一下 dubbo-spring-boot-demo
各工程代码:
父工程pom文件关键部分
<properties>
<dubbo.version>3.2.0-beta.4</dubbo.version>
<spring-boot.version>2.7.8</spring-boot.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
dubbo-spring-boot-demo-interface
:
public interface DemoService {
String sayHello(String name);
}
dubbo-spring-boot-demo-provider
:
pom文件关键部分:
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-demo-interface</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-reload4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- spring boot starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
业务类:
@DubboService
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
return "Hello " + name;
}
}
主启动类:
@SpringBootApplication
@EnableDubbo
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
配置文件:
dubbo:
application:
name: dubbo-springboot-demo-provider
protocol:
name: dubbo
port: -1
registry:
address: zookeeper://${zookeeper.address:192.168.115.129}:2181
dubbo-spring-boot-demo-consumer
:
pom文件关键部分:同 dubbo-spring-boot-demo-provider
主启动类:
@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
配置文件:
dubbo:
application:
name: dubbo-springboot-demo-consumer
protocol:
name: dubbo
port: -1
registry:
address: zookeeper://${zookeeper.address:192.168.115.129}:2181
业务类:
@Component
public class Task implements CommandLineRunner {
@DubboReference
private DemoService demoService;
@Override
public void run(String... args) throws Exception {
String result = demoService.sayHello("world");
System.out.println("Receive result ======> " + result);
new Thread(()-> {
while (true) {
try {
Thread.sleep(1000);
System.out.println(new Date() + " Receive result ======> " + demoService.sayHello("world"));
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}).start();
}
}
三、Dubbo配置
可参考配置手册:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/
这里仅提供部分常用配置:
- 重试次数:用于幂等接口(查询、修改、删除,重复调用不影响的接口),不能用于非幂等接口(新增)
- 超时时间:由于网络或服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间
上面设置分别可通过 @DubboReference
注解的 retries
和 timeout
属性进行设置,如果需要进行全局配置,可参考配置手册
四、高可用
4.1 zookeeper宕机与dubbo直连
现象:zookeeper注册中心宕机,还可以消费dubbo暴露的服务
原因:
- 监控中心宕掉不影响使用,只是丢失部分采样数据
- 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
- 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
- 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
- 服务提供者无状态,任意一台宕掉后,不影响使用
- 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
dubbo直连:通过 @DubboReference
的 url
属性可以设置直接调用服务接口的访问url,无需通过注册中心访问服务
4.2 负载均衡
可通过 @DubboReference
的 loadbalance
属性设置负载均衡策略,可选值
- random:随机,默认
- roundrobin:轮询;
- leastactive:最少活跃调用;
- consistenthash:哈希一致 (2.1.0以上版本);
- shortestresponse:最短响应 (2.7.7以上版本);
多个注解的 stub
属性:缺省代理类,设为true,表示使用缺省代理类名,即:接口名 + Stub后缀,服务接口客户端本地代理类名,用于在客户端执行本地逻辑,如本地缓存等,该本地代理类的构造函数必须允许传入远程代理对象,构造函数如:public XxxServiceStub(XxxService xxxService)
五、服务限流、服务降级、服务容错
@DubboReference
的 mock
属性设置,当 mock="return null"
时,即当服务提供者出现异常(宕机或者业务异常),则返回null给服务消费者
另外 @DubboReference
中提供了一些限流,集群容错的配置,可直接看下面官网,这里不再详述
https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#reference
另外,Dubbo 还可结合其他如 Hystrix 框架,进行服务服务治理。
六、Dubbo 对比 OpenFeign
-
通信协议:Dubbo使用自定义的RPC协议进行通信,而Feign使用HTTP协议进行通信
Dubbo提供了更多的协议支持,包括Dubbo协议、HTTP协议、Hessian协议、Thrift协议等,而OpenFeign仅支持HTTP协议
-
服务调用方式:Dubbo采用的是服务间直接的点对点调用方式,而Feign则是通过服务提供方的统一API网关进行服务调用
-
服务治理:Dubbo提供了更多的负载均衡策略、容错策略和注册中心支持,而OpenFeign则需要依赖于其他组件来实现这些功能
-
同步/异步调用:Dubbo支持同步和异步调用,而Feign主要支持同步调用
-
Dubbo的性能更高,但使用起来相对复杂,需要进行一定的配置和学习,而OpenFeign则更加简单易用
总的来说,Dubbo适用于复杂的分布式系统,提供了更多的功能和灵活性,但使用和配置相对较为复杂。而Feign更适合轻量级的微服务架构,使用简单且易于上手。选择使用哪种框架需要考虑具体的项目需求和实际情况。
Spring Cloud Alibaba 2022版本取消了对 Dubbo 的集成,这是因为 Spring Cloud Alibaba 团队认为 Dubbo 和 Spring Cloud 的设计理念有所不同,无法完全融合。同时,Dubbo 作为一个独立的 RPC 框架,已经有了很成熟的技术和社区,可以独立地和 Spring Cloud 集成使用。因此,取消了对 Dubbo 的集成,也可以让 Spring Cloud Alibaba 团队更加专注于自己的设计和实现。