当前位置 : 主页 > 编程语言 > java >

dubbo服务超时机制

来源:互联网 收集:自由互联 发布时间:2022-07-05
内容出自 图灵学院 我做完了作业,然后整理了整理代码,发了个博客 概念 在服务提供者和服务消费者上都可以配置服务超时时间,这两者是不一样的。 消费者调用一个服务,分为三步:

内容出自 图灵学院 我做完了作业,然后整理了整理代码,发了个博客

概念

在服务提供者和服务消费者上都可以配置服务超时时间,这两者是不一样的。

消费者调用一个服务,分为三步:

  • 消费者发送请求(网络传输)
  • 服务端执行服务
  • 服务端返回响应(网络传输)
  • 如果在服务端和消费端只在其中一方配置了timeout,那么没有歧义,表示消费端调用服务的超时时间,消费端如果超过时间还没有收到响应结果,则消费端会抛超时异常,但,服务端不会抛异常,服务端在执行服务后,会检查执行该服务的时间,如果超过timeout,则会打印一个超时日志。服务会正常的执行完。

    如果在服务端和消费端各配了一个timeout,那就比较复杂了,假设

  • 假如服务执行为5s
  • 消费端timeout配置为3s
  • 服务端timeout配置为6s
  • 那么消费端调用服务时,消费端超过3秒回抛出超时异常,服务端一切正常(因为服务端超时配置的是6秒,没有超时)。

    服务消费者调用超时之后会触发下面这样的异常

    Caused by: java.util.concurrent.ExecutionException: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2021-12-11 21:04:11.590, end time: 2021-12-11 21:04:14.620, client elapsed: 1 ms, server elapsed: 3029 ms, timeout: 3000 ms, request: Request [id=2, version=2.0.2, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=sayHello, parameterTypes=[class java.lang.String], arguments=[周瑜], attachments={path=com.tuling.DemoService, remote.application=dubbo-consumer-demo, interface=com.tuling.DemoService, version=default, timeout=3000}]], channel: /172.16.10.1:57506 -> /172.16.10.1:20880

    配置方式

    provider

    // timeout = 6000 定义服务的时候可以配置一个超时时间
    @Service(version = "default",timeout = 6000)
    public class DefaultDemoService implements DemoService {

    consumer

    // 如果超过3秒还没调用成功,那么就会抛出异常, 如果你想等调用完成,那么就将timeout属性配置大一些
    @Reference(version = "default", timeout = 3000)
    private DemoService demoService;

    代码地址

    ​​https://gitee.com/zjj19941/ZJJ_Dubbo.git​​​ 看 timeout 项目自己准备个zookeeper安装启动好了,改改配置文件zookeeper地址,然后依次启动provider和consumer,就可以看到效果

    运行过程中控制台

    consumer

    因为consumer配置超时时间为3秒,但是provider处理要5秒多,consumer调用超时,抛出了这个异常 ,

    Caused by: java.util.concurrent.ExecutionException: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2021-12-11 21:04:11.590, end time: 2021-12-11 21:04:14.620, client elapsed: 1 ms, server elapsed: 3029 ms, timeout: 3000 ms, request: Request [id=2, version=2.0.2, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=sayHello, parameterTypes=[class java.lang.String], arguments=[周瑜], attachments={path=com.tuling.DemoService, remote.application=dubbo-consumer-demo, interface=com.tuling.DemoService, version=default, timeout=3000}]], channel: /172.16.10.1:57506 -> /172.16.10.1:20880

    如果你不想抛异常,并且让请求调用正常,那么就需要调整consumer那边配置的timeout属性,给timeout属性调整大一点,至少要比provider处理时间大一些,这样就不会因为等待时间过长调用超时了.

    // 如果超过3秒还没调用成功,那么就会抛出异常, 如果你想等调用完成,那么就将timeout属性配置大一些
    @Reference(version = "default", timeout = 10000)
    private DemoService demoService;

    provider

    执行了timeout服务周瑜
    执行了timeout服务周瑜
    执行结束周瑜
    执行了timeout服务周瑜
    执行结束周瑜
    执行结束周瑜

    结果发现我consumer只是执行了一次,为什么provider控制台出现三条请求记录???
    因为consumer调用超时了,跑了异常了,而dubbo有集群容错机制,如果调用失败了,dubbo还进行重试调用其它的provider.
    为什么咱们这个日志打了三条请求记录,因为我这个案例只启动了一台provider,
    consumer在调用provider调用失败之后,会进行重试机制,默认是两次,因为我这里只是启动了一台provider服务,所以dubbo重试机制的两次机会当然也就请求到了这唯一的provider机器上了.
    所以这就是为什么provider有三条请求日志了,第一条请求日志是真正的请求,后两条请求日志是dobbo重试机制请求的日志.


    上一篇:Linux之rsync同步分发脚本编写.
    下一篇:没有了
    网友评论