Dubbo - 配置示例使用详解

查看Dubbo完整配置示例,参考官方文档

【1】启动时检查

Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"

可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。

另外,如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭 check,否则服务临时不可用时,会抛出异常,拿到 null 引用,如果 check="false",总是会返回引用,当服务恢复时,能自动连上。

① 通过 spring 配置文件

关闭某个服务的启动时检查 (没有提供者时报错):

<dubbo:reference interface="com.foo.BarService" check="false" />

关闭所有服务的启动时检查 (没有提供者时报错):

<dubbo:consumer check="false" />

关闭注册中心启动时检查 (注册订阅失败时报错):

<dubbo:registry check="false" />

② 通过 dubbo.properties

dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false

③ 通过 -D 参数

java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false 
java -Ddubbo.registry.check=false

④ 配置的含义

dubbo.reference.check=false,强制改变所有 reference 的 check 值,就算配置中有声明,也会被覆盖。如<dubbo:reference interface="com.foo.BarService" check="true" />虽然设置了true,同样按照false处理。

dubbo.consumer.check=false,是设置 check 的缺省值,如果配置中有显式的声明,如:<dubbo:reference interface="com.foo.BarService" check="true" />,则不会受影响。那些没有显示设置check的reference 将会受到影响。

dubbo.registry.check=false,前面两个都是指订阅成功,但提供者列表是否为空是否报错,如果注册订阅失败时,也允许启动,需使用此选项,将在后台定时重试。


⑤ Dubbo的配置

Dubbo的配置有xml配置、属性配置、API配置和注解配置。XML配置和注解配置就是常规项目中用到的两种方式,一种是完全使用xml,如传统项目;一种似乎使用注解代替,如SpringBoot。详情参考官方文档

这里说一下属性配置,如上面看到的①②③。

如果公共配置很简单,没有多注册中心,多协议等情况,或者想多个 Spring 容器想共享配置,可以使用 dubbo.properties 作为缺省配置。

Dubbo 将自动加载 classpath 根目录下的 dubbo.properties,可以通过JVM启动参数-Ddubbo.properties.file=xxx.properties 改变缺省配置位置。

覆盖策略
在这里插入图片描述
JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。

XML 次之,如果在 XML 中有配置,则 dubbo.properties 中的相应配置项无效。

Properties 最后,相当于缺省值,只有 XML 没有配置时,dubbo.properties 的相应配置项才会生效,通常用于共享公共配置,比如应用名。


【2】服务调用超时设置和重试次数

① 超时timeout属性设置

当调用一个服务长时间得不到响应的时候,并不会让其一直阻塞等待下去。大量线程阻塞等待响应会引起性能下降,这时就需要设置超时属性-timeout。

dubbo:reference的timeout属性缺省使用<dubbo:consumer>的timeout属性,而后者的timeout属性缺省值为1000。参考schema配置参考手册

服务消费者配置实例如下:

<dubbo:reference interface="com.web.gmall.service.UserService" 
		id="userService" timeout="5000" >
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
</dubbo:reference>

<!-- 配置当前消费者的统一规则:所有的服务都不检查 -->
<dubbo:consumer check="false" timeout="5000"></dubbo:consumer>

服务提供者配置实例如下:

<!-- 暴露服务   ref:指向服务的真正的实现对象 -->
<dubbo:service interface="com.web.gmall.service.UserService" 
	ref="userServiceImpl" timeout="1000" >
	<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
</dubbo:service>
	
<!--统一设置服务提供方的规则  -->
<dubbo:provider timeout="1000"></dubbo:provider>

这时候就有有个问题,哪个配置的timeout属性生效?

在官方文档xml配置中,说明了该问题。


② xml配置覆盖关系

以 timeout 为例,显示了配置的查找顺序,其它 retries, loadbalance, actives 等类似:

  • 方法级优先,接口级次之,全局配置再次之。
  • 如果级别一样,则消费方优先,提供方次之。

其中,服务提供方配置,通过 URL 经由注册中心传递给消费方。

在这里插入图片描述
建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。

理论上 ReferenceConfig 的非服务标识配置,在 ConsumerConfig,ServiceConfig, ProviderConfig 均可以缺省配置。


③ 重试次数retries属性

为了提高可用性和冗错率,可以设置retries属性。dubbo:reference的retries属性缺省使用<dubbo:consumer>的retries属性。而<dubbo:consumer>的retries属性默认值为2。

消费者实例设置如下:

<dubbo:reference interface="com.web.gmall.service.UserService" 
		id="userService" timeout="5000" retries="3" >
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
</dubbo:reference>
//设置retries="3"表示除第一次调用外再尝试调用三次,总共调用四次。

如果服务提供者如UserService有多个实例,消费者重试的时候还会尝试调用其他UserService实例。

那么是否所有情况下都应该设置重试次数?答案当然是否定的!

如果每次的操作结果都一样,那么应该可以进行重试,这种情况称之为幂等。如果每次操作结果都不一样,那么不应该能够重试,这种情况称之为非幂等。幂等操作如查询、删除和修改,非幂等操作如新增。

举个例子,如消费者调用提供者进行数据库新增,在提供者插入数据库过程中,消费者超时了,这时就不应该再次重试。

禁止重试,只需要将retries设置为0即可。如下所示:

<dubbo:reference interface="com.web.gmall.service.UserService" 
		id="userService" timeout="5000" retries="3" version="*">
		<dubbo:method name="insertUser" timeout="1000" retries="0"></dubbo:method>

接口级别可以重试三次,insertUser该方法禁止重试。

故而在系统设计的时候重试次数一定要额外注意,该值默认值为2。


【3】多版本

当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。

可以按照以下的步骤进行版本迁移:

  • 0.在低压力时间段,先升级一半提供者为新版本
  • 1.再将所有消费者升级为新版本
  • 2.然后将剩下的一半提供者升级为新版本

老版本服务提供者配置:

<dubbo:service interface="com.foo.BarService" version="1.0.0" />

新版本服务提供者配置:

<dubbo:service interface="com.foo.BarService" version="2.0.0" />

老版本服务消费者配置:

<dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" />

新版本服务消费者配置:

<dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" />

如果不需要区分版本,可以按照以下的方式配置 :

<dubbo:reference id="barService" interface="com.foo.BarService" version="*" />

这样就可以从旧版本平滑过渡到新版本,也就是Dubbo官网介绍的灰度发布。


【4】本地存根Stub

远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,比如:做 ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在 API 中带上 Stub,客户端生成 Proxy 实例,会把 Proxy 通过构造函数传给 Stub,然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。

在这里插入图片描述

dubbo:service的stub属性

值类型为class/boolean,默认值为false。设为true,表示使用缺省代理类名,即:接口名 + Local后缀,服务接口客户端本地代理类名,用于在客户端执行本地逻辑,如本地缓存等,该本地代理类的构造函数必须允许传入远程代理对象,构造函数如:public XxxServiceLocal(XxxService xxxService)

实例

如下所示,这里将接口抽取到了gmall-interface项目中,order-service-consumer和user-service-provider均依赖该项目。故而在gmall-interface项目中,添加UserServiceStub即可。

UserServiceStub实例如下:

public class UserServiceStub implements UserService {
	
	private final UserService userService;
	

	/**
	 * 传入的是userService远程的代理对象
	 * @param userService
	 */
	public UserServiceStub(UserService userService) {
		super();
		this.userService = userService;
	}


	@Override
	public List<UserAddress> getUserAddressList(String userId) {
		// TODO Auto-generated method stub
		System.out.println("UserServiceStub.....");
		if(userId!=null&&userId!="") {
			return userService.getUserAddressList(userId);
		}
		return null;
	}

}

在user-service-provider项目中配置如下:

<dubbo:service  interface="com.web.gmall.service.UserService" 
		ref="userServiceImpl" timeout="1000"  
		stub="com.web.gmall.service.stub.UserServiceStub" >
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
</dubbo:service>

分别启动provider和consumer,测试如下:

用户id:1
UserServiceStub.....
北京市昌平区宏福科技园综合楼3层
深圳市宝安区西部硅谷大厦B座3层(深圳分校)
调用完成...

可以看到在发起远程调用之前,首先调用了UserServiceStub 。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值