七、Dubbo配置

Dubbo目录



七、Dubbo配置

所有的配置在官方文档都有介绍

dubbo配置官网参考 :Schema 配置参考手册 | Apache Dubbo用法示例 | Apache Dubbo

在于SpringBoot整合的配置文件 application.properties 中的配置,和这些标签是一一对应的,所有标签均可在配置文件中进行配置。

1、配置原则

Duboo 对这些配置,让其生效,有三种策略:

7-1

  • JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。

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

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

2、启动时检查

启动时检查 | Apache Dubbo

在启动时检查依赖的服务是否可用

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

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

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

操作示例:

在consumer.xml中修改配置:

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

	<!-- 3、生成远程服务代理,可以和本地bean一样使用demoService -->
	<!--声明需要调用的远程服务的接口;生成远程服务代理  -->
	<dubbo:reference interface="com.wlw.dubbo.service.UserService"
					 id="userService" check="false">
	</dubbo:reference>

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

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

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

	<dubbo:registry check="false" />

3、超时时间 与重试次数

超时时间的配置:由于网络或服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。

重试次数的配置:失败自动切换,当出现失败,重试其它服务器(如果有的话),但重试会带来更长延迟。可通过 retries=“2” 来设置重试次数(不含第一次)。

	<!-- 3、生成远程服务代理,可以和本地bean一样使用demoService -->
	<!--声明需要调用的远程服务的接口;生成远程服务代理  -->
	<!-- 配置生效优先级:
		1)、精确优先 (方法级优先,接口级次之,全局配置再次之)
		2)、消费者设置优先(如果级别一样,则消费方优先,提供方次之)
	-->
	<!--超时时间: timeout="0" 默认是1000ms-->
	<!--重试次数 retries="" 不包含第一次调用,0代表不重试;
		幂等的方法(设置重试次数)比如:查询、删除、修改操作
		非幂等的方法(不能设置重试次数)比如:新增
	-->
	<dubbo:reference interface="com.wlw.dubbo.service.UserService"
					 id="userService" timeout="5000" retries="2">
		<!--精确到方法的配置-->
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
	</dubbo:reference>

4、XML 配置覆盖关系

XML 配置 | Apache Dubbo

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

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

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

7-2

dubbo推荐在Provider上尽量多配置Consumer端属性:

  • 1、作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等

  • 2、在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可以作为Consumer的缺省值。否则,Consumer会使用Consumer端的全局设置,这对于Provider不可控的,并且往往是不合理的

5、多版本

多版本 | Apache Dubbo

在 Dubbo 中为同一个服务配置多个版本

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

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

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

provider.xml:

	<!-- 4、暴露服务   ref:指向服务的真正的实现对象 -->
	<!-- 老服务 -->
	<dubbo:service interface="com.wlw.dubbo.service.UserService"
				   ref="userServiceImpl01" timeout="2000" version="1.0.0">
	</dubbo:service>
	<!-- 服务的实现 -->
	<bean id="userServiceImpl01" class="com.wlw.dubbo.service.impl.UserServiceImpl"></bean>

	<!-- 新服务 -->
	<dubbo:service interface="com.wlw.dubbo.service.UserService"
				   ref="userServiceImpl02" timeout="2000" version="2.0.0">
	</dubbo:service>
	<bean id="userServiceImpl02" class="com.wlw.dubbo.service.impl.UserServiceImpl2"></bean>

consumer.xml:指定哪个版本的服务,这样在启动时,就会调用对应的方法

	<dubbo:reference interface="com.wlw.dubbo.service.UserService"
					 id="userService" timeout="5000" retries="2" version="2.0.0">
		<!--精确到方法的配置-->
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
	</dubbo:reference>
  • 如果不需要区分版本,可以按照以下的方式配置 :version="*",它会随机选择版本服务。提示:2.2.0 以上版本支持

    	<dubbo:reference interface="com.wlw.dubbo.service.UserService"
    					 id="userService" timeout="5000" retries="2" version="*">
    		<!--精确到方法的配置-->
    		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
    	</dubbo:reference>
    

6、本地存根

本地存根 | Apache Dubbo

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

7-3

我们这是在消费者中配置:(在生产中应该在公共接口层对接口进行配置)

增加UserServiceStub:

package com.wlw.dubbo.service.impl;

import com.wlw.dubbo.bean.UserAddress;
import com.wlw.dubbo.service.UserService;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 本地存根
 */
public class UserServiceStub implements UserService {

    private final UserService userService;

    /**
     * 构造函数传入真正的远程代理对象
     * 传入的是userService 的远程代理对象
     * @param userService
     */
    public UserServiceStub(UserService userService) {
        this.userService = userService;
    }

    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("UserServiceStub..............");
        if(!StringUtils.isEmpty(userId)) {
            return userService.getUserAddressList(userId);
        }
        return null;
    }
}

consumer.xml:增加配置:

	<dubbo:reference interface="com.wlw.dubbo.service.UserService"
					 id="userService" timeout="5000" retries="2" version="2.0.0"
					 stub="com.wlw.dubbo.service.impl.UserServiceStub">
		<!--精确到方法的配置-->
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
	</dubbo:reference>

测试结果:

7-4

7、配置 与SpringBoot整合的三种方式

第一种(也就是六、Dubbo与SpringBoot整合)使用的方式:

  • 导入依赖
  • 配置文件 application.properties 中增加配置
  • 提供者:暴漏服务,通过注解(com.alibaba.dubbo.config.annotation.Service) 来实现;消费者:远程引用指定的服务,注解:com.alibaba.dubbo.config.annotation.Reference;
  • 启动类开启Dubbo,注解:@EnableDubbo

第二种(保留Dubbo 相关的xml配置文件,这样就可以做到方法级别的配置,上面第一种是不行的):

  • 导入依赖

  • 保留Dubbo 相关的xml配置文件

  • 在启动类使用注解@ImportResource导入Dubbo的xml配置文件:

    @ImportResource(locations="classpath:provider.xml")
    
  • 这种情况下,就不需要注解(com.alibaba.dubbo.config.annotation.Service) 来暴漏服务了

第三种,使用 注解API的方式,可以实现方法级配置:

  • 将每一个组件手动配置到容器中,让dubbo来扫描其他的组件

  • 这种情况是需要注解(com.alibaba.dubbo.config.annotation.Service) 来暴漏服务了

  • 在启动类中添加注解:@EnableDubbo(scanBasePackages = “com.wlw.dubbo”)

  • 配置类

    package com.wlw.dubbo.config;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.wlw.dubbo.service.UserService;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.alibaba.dubbo.config.ApplicationConfig;
    import com.alibaba.dubbo.config.MethodConfig;
    import com.alibaba.dubbo.config.MonitorConfig;
    import com.alibaba.dubbo.config.ProtocolConfig;
    import com.alibaba.dubbo.config.ProviderConfig;
    import com.alibaba.dubbo.config.RegistryConfig;
    import com.alibaba.dubbo.config.ServiceConfig;
    
    
    @Configuration
    public class MyDubboConfig {
    
    	//<dubbo:application name="boot-user-service-provider"></dubbo:application>
    	@Bean
    	public ApplicationConfig applicationConfig() {
    		ApplicationConfig applicationConfig = new ApplicationConfig();
    		applicationConfig.setName("boot-user-service-provider");
    		return applicationConfig;
    	}
    	
    	//<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
    	@Bean
    	public RegistryConfig registryConfig() {
    		RegistryConfig registryConfig = new RegistryConfig();
    		registryConfig.setProtocol("zookeeper");
    		registryConfig.setAddress("127.0.0.1:2181");
    		return registryConfig;
    	}
    	
    	//<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
    	@Bean
    	public ProtocolConfig protocolConfig() {
    		ProtocolConfig protocolConfig = new ProtocolConfig();
    		protocolConfig.setName("dubbo");
    		protocolConfig.setPort(20880);
    		return protocolConfig;
    	}
    	
    	/**
    	 *<dubbo:service interface="com.atguigu.gmall.service.UserService" 
    		ref="userServiceImpl01" timeout="1000" version="1.0.0">
    		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
    	</dubbo:service>
    	 */
    	@Bean
    	public ServiceConfig<UserService> userServiceConfig(UserService userService){
    		ServiceConfig<UserService> serviceConfig = new ServiceConfig<>();
    		serviceConfig.setInterface(UserService.class);
    		serviceConfig.setRef(userService);
    		serviceConfig.setVersion("1.0.0");
    		
    		//配置每一个method的信息
    		MethodConfig methodConfig = new MethodConfig();
    		methodConfig.setName("getUserAddressList");
    		methodConfig.setTimeout(1000);
    		
    		//将method的设置关联到service配置中
    		List<MethodConfig> methods = new ArrayList<>();
    		methods.add(methodConfig);
    		serviceConfig.setMethods(methods);
    
    		return serviceConfig;
    	}
    
    	//ProviderConfig
    	//MonitorConfig
    }
    
    
  • 启动类:

    package com.wlw.dubbo;
    
    import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ImportResource;
    
    //@EnableDubbo
    //@ImportResource(locations = "classpath:provider.xml")
    @EnableDubbo(scanBasePackages = "com.wlw.dubbo")
    @SpringBootApplication
    public class BootUserServiceProviderApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(BootUserServiceProviderApplication.class, args);
    	}
    }
    

8、详细代码

详细代码:具体的配置操作,都是提交记录:wlw/dubboDemo (gitee.com)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

悬浮海

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

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

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

打赏作者

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

抵扣说明:

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

余额充值