SpringBoot整合Dubbo
相比于上面ssm项目繁琐的xml配置,SpringBoot就简洁的多。
1.添加dubbo-spring-boot-starter依赖,其中直接包含了dubbo和zookeeper客户端
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.7</version>
</dependency>
2.之前在xml中的配置改由application.properties
配置,包括服务的名称、注册中心中的位置和通信协议名称与端口号。
# Spring boot application
spring.application.name=dubbo-auto-configuration-provider-demo
# Base packages to scan Dubbo Component: @org.apache.dubbo.config.annotation.Service
dubbo.scan.base-packages=org.apache.dubbo.spring.boot.sample.provider.service
# Dubbo Application
## The default value of dubbo.application.name is ${spring.application.name}
## dubbo.application.name=${spring.application.name}
# Dubbo Protocol
dubbo.protocol.name=dubbo
dubbo.protocol.port=12345
## Dubbo Registry
dubbo.registry.address=N/A
3.提供者对于要暴露的服务接口,xml配置时每个服务都要配置一系列标签。而在SpringBoot可以在接口上使用com.alibaba.dubbo.config.annotation下的@Service
注解,就可以将服务暴露出来。
同理消费者声明要调用的远程服务也有@Reference
注解来代替繁琐的xml配置。
同时要在启动类上标注@EnableDubbo
注解,开启基于注解的dubbo功能。
SpringBoot中也可以继续使用xml配置:
只要在启动类上使用@ImportResource(locations=“classpath:spring-provider.xml”)注解导入dubbo配置文件即可。
除了xml和注解,也可以使用Java配置类的方式手动配置Dubbo,同时开启@EnableDubbo注解,扫描配置类中的各个组件
Dubbo属性配置的三种方式与优先级
优先级从高到低:
- JVM -D 参数:当你部署或者启动应用时,它可以轻易地重写配置,比如,改变 dubbo 协议端口;
- XML:XML 中的当前配置会重写 dubbo.properties 中的;
- Properties:默认配置,仅仅作用于以上两者没有配置时。
- 如果在 classpath 下有超过一个 dubbo.properties 文件,比如,两个 jar 包都各自包含了 dubbo.properties,dubbo 将随机选择一个加载,并且打印错误日志。
- 如果
id
没有在protocol
中配置,将使用name
作为默认属性。
(对于公共的属性建议在dubbo.properties中配置,dubbo.xml可以放些额外需要改变的配置,而JVM -D参数可以放些临时配置)
启动时检查
在启动时检查依赖的服务是否可用
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"
。
(比如消费者启动之前会检查要调用的服务是否在注册中心存在,如果不存在则启动失败,改为check="false"将不会检查,直接启动。直到调用这个服务时才向注册中心发起检查)
如何设置?配置远程引用时即可配置:
<dubbo:reference id="demoService" interface="org.apache.dubbo.demo.DemoService" check="false"/>
如果消费者有多个服务需要调用,可以设置所有消费者服务都不检查
<dubbo:consumer check="false"></dubbo:consumer>
【timeout属性超时配置,默认是1000ms】
- 精确优先:方法级优先、接口级次之,全局配置再次之
- 消费者优先:级别一样则消费方优先,提供方次之
【retries="":重试次数,不包含第一次调用】
幂等方法(可以设置重试次数)[查询、删除、修改];非幂等方法(不能设置重试次数)[新增]
【幂等:同样的方法带同样的参数,无论执行多少次,产生的效果都与第一次执行产生的效果一样;非幂等:每次执行都会产生新的结果】
【version="":版本控制,声明使用哪个版本的服务,即实现了灰度发布】
(消费者可以配置version="*",不声明具体版本,将随机调用版本)
本地存根
在 Dubbo 中利用本地存根在客户端执行部分逻辑
远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,比如:做 ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在 API 中带上 Stub,客户端生成 Proxy 实例,会把 Proxy 通过构造函数传给 Stub ,然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。
在 消费者spring 配置文件中按以下方式配置实现本地存根:
<dubbo:reference interface="com.foo.BarService" stub="true" />
或
<dubbo:reference interface="com.foo.BarService" stub="com.foo.BarServiceStub" />
在消费方提供 Stub 的实现
package com.foo;
public class BarServiceStub implements BarService {
private final BarService barService;
// 构造函数传入真正的远程代理对象
public BarServiceStub(BarService barService){
this.barService = barService;
}
public String sayHello(String name) {
// 此代码在客户端执行, 你可以在客户端做ThreadLocal本地缓存,或预先验证参数是否合法,等等
try {
return barService.sayHello(name);
} catch (Exception e) {
// 你可以容错,可以做任何AOP拦截事项
return "容错数据";
}
}
}