dubbo配置之属性配置原则、启动检查、超时时间、重试次数、多版本

之前我们简单介绍了dubbo配置服务提供者、消费者以及管理平台监控平台,接下来我们再说一下dubbo的其他配置。

1.配置策略

1.1 属性配置

dubbo可以在JVM 启动参数dubboXMLdubbo.properties 三个地方配置相关属性,这里我们以端口为例.

  • JVM 启动参数
    我们可以在启动项目时配置VM参数
    在这里插入图片描述
-Ddubbo.protocol.port=20883
  • dubboXML
<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
  • dubbo.properties
dubbo.protocol.port=20881

覆盖策略
在这里插入图片描述

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

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

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

1.2 XML配置

前面介绍了服务提供者接口的配置

<dubbo:service interface="com.yz.dubbo.api.IUserService" ref="userService1" timeout="1000"></dubbo:service>

当然我们只是把timeout 属性配置在了接口上,而接口中有那么多方法,所以我们还可以具体配置到方法

<dubbo:service interface="com.yz.dubbo.api.IUserService" ref="userService1" >
	<dubbo:method name="getUser" timeout="2000"></dubbo:method>
</dubbo:service>

这样我们就指定了getUser 方法timeout 属性

但是服务提供者和消费者有那么多的接口一个一个配置岂不是太麻烦,所以我们可以将一样的配置抽取出来作为服务提供者以及消费者的缺省配置

<dubbo:provider timeout="3000"></dubbo:provider>

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

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

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

2.启动检查

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

可以通过 check=“false” 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
例子
当我们没有配置检查属性的时候.只启动消费者,可以看到控制台输出错误信息 No provider

在这里插入图片描述

我们配置启动检查checkfalse

<dubbo:reference id="userService" interface="com.yz.dubbo.api.IUserService" check="false"></dubbo:reference>

当我们设置check="false" 时,在没有提供者的情况下,消费者启动是不会报错的

       ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] { "classpath:customer.xml" });
        final IUserService demoService = (IUserService) context.getBean("userService");
//        System.out.println(demoService.getUser());
        System.out.println("程序运行......");
        System.in.read();

在这里插入图片描述
,只有在显示调用提供者服务的时候才会报错

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] { "classpath:customer.xml" });
        final IUserService demoService = (IUserService) context.getBean("userService");
        System.out.println(demoService.getUser());
        System.out.println("程序运行......");
        System.in.read();

在这里插入图片描述

可以看到程序报错,就是显示调用 demoService.getUser()这段代码导致的
注册中心检查

dubbo.registry.check=false

我们可以通过以上配置关闭服务提供者消费者对注册中心的检查,这样注册中心挂掉了,我们服务提供者消费者启动也不会报错,只是不能注册服务而已…
例子
当我们的注册中心挂掉的时候,我们启动服务消费者以及提供者是会报错的
在这里插入图片描述
在这里插入图片描述

我们只需要配置注册中心不检查,启动就不会报错而且当注册中心重新恢复的时候他们会自动的订阅服务以及注册服务

<dubbo:registry address="zookeeper://127.0.0.1:2181" check="false"></dubbo:registry>

3.超时时间

由于网络或服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。
在现实的开发中我们往往一些服务提供者的调用比较耗时,而dubbo的timeout缺省配置为1000 毫秒,也就是说当消费者调用服务提供者一秒钟还没有返回结果,则消费者会报错,如下
提供者

public class UserServiceImpl implements IUserService{
    @Override
    public List<User> getUser() throws UserException {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Arrays.asList(new User[]{new User(1,"yz","china","hlj")
                ,new User(2,"zwl","china","ah")
                ,new User(3,"hhj","china","zj")});
    }
}

我们模拟耗时,让提供者睡眠三秒钟,接下来启动提供者消费者
在这里插入图片描述

可以看到消费者在等待一秒后还没有结果就报错,所以在线上我们可以通过设置timeout来避免提供者服务耗时带来的问题

<dubbo:service interface="com.yz.dubbo.api.IUserService" ref="userService1" timeout="4000"></dubbo:service>

在这里插入图片描述

消费者在等待三秒后,提供者服务已经被正常调用

4.重试次数

当我们服务消费者消费出现失败,可通过 retries="2" 来设置重试次数(不含第一次),多次调用服务提供者
例子
首先我们去掉之前的timeout 属性来模拟出错,并加上retries 来实现重试

<dubbo:reference id="userService" interface="com.yz.dubbo.api.IUserService" check="false" retries="3"></dubbo:reference>

提供者

    try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("被调用了............");

        return Arrays.asList(new User[]{new User(1,"yz","china","hlj")
                ,new User(2,"zwl","china","ah")
                ,new User(3,"hhj","china","zj")});

接下来我们分别启动服务提供者与消费者,可以看到,我们消费者在调用失败后提供者被调用了四次
在这里插入图片描述
在这里插入图片描述

5.多版本

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

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

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

也就实现了dubbo所说的灰度发布

例子
首先我们创建提供者接口两个不同实现

UserServiceImpl

@Override
    public List<User> getUser() throws UserException {
        System.out.println("被调用了1............");

        return Arrays.asList(new User[]{new User(1,"yz","china","hlj")
                ,new User(2,"zwl","china","ah")
                ,new User(3,"hhj","china","zj")});
    }

UserServiceImpl2

@Override
    public List<User> getUser() throws UserException {
        System.out.println("被调用了2............");

        return Arrays.asList(new User[]{new User(1,"yz","china","hlj")
                ,new User(2,"zwl","china","ah")
                ,new User(3,"hhj","china","zj")});
    }

接下来在provider.xml配置文件中提供者接口实现指向不同的两个类,并指定不同的版本

    <bean id="userService1" class="com.yz.dubbo.impl.UserServiceImpl"></bean>

    <bean id="userService2" class="com.yz.dubbo.impl.UserServiceImpl2"></bean>

    <dubbo:service interface="com.yz.dubbo.api.IUserService" ref="userService1" version="1.0.0"></dubbo:service>

    <dubbo:service interface="com.yz.dubbo.api.IUserService" ref="userService2" version="2.0.0"></dubbo:service>

customer.xml 中指定消费者的版本号为1.0.0

<dubbo:reference id="userService" interface="com.yz.dubbo.api.IUserService" check="false" version="1.0.0"></dubbo:reference>

在这里插入图片描述

customer.xml 中指定消费者的版本号为2.0.0

<dubbo:reference id="userService" interface="com.yz.dubbo.api.IUserService" check="false" version="2.0.0"></dubbo:reference>

在这里插入图片描述

可以看到了通过指定版本号分别调用了不同的接口实现,这样在实际开发中就能够实现新旧功能的过度

展开阅读全文

没有更多推荐了,返回首页