Dubbo(三)配置说明

配置说明

启动时检查

启动时会在注册中心检查依赖的服务是否可用,不可用时会抛出异常
在消费方编写初始化容器的main方法启动(tomcat启动方式,必须访问一次action才能初始化spring)

/**
 * @Program: dubbo_test2
 * @Author: XiaoXing
 * @Create: 2021-01-16 13:35
 * @Description: 启动时检查
 **/
public class TestCheckException {

    public static void main(String[] args) {
        //初始化spring
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/spring.xml");

        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
	
    <dubbo:consumer check="false" />
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %m%n
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=dubbo.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %m%n
log4j.rootLogger=error, stdout,file

超时时间

由于网络或服务端不可靠,会导致调用过程中出现不确定的阻塞状态(超时)
为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间
在服务提供者添加如下配置:


<dubbo:provider timeout="2000"/>

可以将服务实现HelloServiceImpl.java中加入模拟的网络延迟进行测试:

@Service
public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Hello " + name + " !!!";
    }

}

超时设置2秒,而模拟的网络延迟有3秒,超出时限,报错!

Dubbo(三)配置说明_第1张图片

配置原则:

  • dubbo推荐在Provider上尽量多配置Consumer端属性:
    • 作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等
    • 在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可以作消费者的缺省值。

重试次数

当出现失败,自动切换并重试其它服务器,dubbo重试的缺省值是2次,我们可以自行设置
在provider提供方配置:


<dubbo:provider timeout="2000" retries="3"/>
@Service
public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
        System.out.println("被调用1次");
        try {
            //模拟网络延迟
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Hello " + name + " !!!";
    }

}
  • 并不是所有的方法都适合设置重试次数

    • 幂等方法:适合(当参数一样,无论执行多少次,结果是一样的,例如:查询,修改)
    • 非幂等方法:不适合(当参数一样,执行结果不一样,例如:删除,添加)
  • 单独设置某个方法

    public interface HelloService {
    
        public String sayHello(String name);
    
        public String sayNo();
    
    }
    
    @Override
    public String sayNo() {
        System.out.println("------------no--------------");
        return "no";
    }
    

    消费方接口添加sayNo()方法声明

    public interface HelloService {
    
        String sayHello( String name );
    
        public String sayNo();
    
    }
    
    @Controller
    public class HelloAction {
    
    //    @Reference  // 远程去服务方将service的实现类注入进来
        @Autowired
        private HelloService helloService;
    
        @RequestMapping("/hello")
        @ResponseBody
        public String sayHi(String name){
            System.out.println(name);
            return helloService.sayHello(name);
        }
    
        @RequestMapping("/no")
        @ResponseBody
        public String sayNo(){
            return helloService.sayNo();
        }
    
    }
    

    消费方配置方法重试次数

    <dubbo:reference interface="service.HelloService" id="helloService">
        <dubbo:method name="sayHello" retries="3">dubbo:method>
        <dubbo:method name="sayNo" retries="0">dubbo:method>
    dubbo:reference>
    

多版本

一个接口,多个(版本的)实现类,可以使用定义版本的方式引入
为HelloService接口定义两个实现类,提供者修改配置:


<dubbo:service interface="service.HelloService" class="service.impl.HelloServiceImpl01" version="1.0.0">dubbo:service>
<dubbo:service interface="service.HelloService" class="service.impl.HelloServiceImpl02" version="2.0.0">dubbo:service>

消费者就可以根据version的版本,选择具体的服务版本

<dubbo:reference interface="service.HelloService" id="helloService" version="1.0.0">
    <dubbo:method name="sayHello" retries="3">dubbo:method>
    <dubbo:method name="sayNo" retries="0">dubbo:method>
dubbo:reference>

注意:消费者的控制层要改为自动注入,因为@Reference注解和 dubbo:reference在这里冲突

@Controller
public class HelloAction {

//    @Reference  // 远程去服务方将service的实现类注入进来
    @Autowired
    private HelloService helloService;
}

当消费者的版本修改为 version="*",那么就会随机调用服务提供者的版本

本地存根

目前我们的分布式架构搭建起来有一个严重的问题,就是所有的操作全都是 消费者发起,由服务提供者执行
消费者动动嘴皮子却什么活都不干,这样会让提供者很累,例如简单的参数验证,消费者完全能够胜任,把合法的参数再发送给提供者执行,效率高了,提供者也没那么累了
例如:去房产局办理房屋过户,请带好自己的证件和资料,如果什么都不带,那么办理过户手续会很麻烦,得先调查你有什么贷款,有没有抵押,不动产证是不是你本人,复印资料等操作。一天肯定办不完。明天还要来。如果你能提前将这些东西准备好,办理过户,1个小时足矣,这就是“房产中介办事效率高的原因”
话不多说,先在消费者处理一些业务逻辑,再调用提供者的过程,就是“本地存根”
代码实现肯定在 消费者,创建一个HelloServiceStub类并且实现HelloService接口
注意:必须使用构造方法的方式注入

public class HelloServiceStub implements HelloService {

    private HelloService helloService;

    //本地存根必须以构造方法的形式注入
    public HelloServiceStub(HelloService helloService){
        this.helloService = helloService;
    }

    @Override
    public String sayHello(String name) {
        if (!StringUtils.isEmpty(name)){
            return helloService.sayHello(name);
        }
        return "i am sorry!";
    }

    @Override
    public String sayNo() {
        return helloService.sayNo();
    }
}

修改消费者配置

<dubbo:reference interface="service.HelloService" id="helloService" version="2.0.0" stub="stub.HelloServiceStub">
    <dubbo:method name="sayHello" retries="3">dubbo:method>
    <dubbo:method name="sayNo" retries="0">dubbo:method>
dubbo:reference>

你可能感兴趣的:(java,spring,zookeeper,dubbo)