Dubbo应用与异常记录

结合项目里使用暴露出的问题,对并发较多的核心业务或者对请求失败敏感的业务场景不建议使用Dubbo,java

如电商的购买行为,使用Dubbo最好阅读源码,熟悉相关机制,或者直接本身造轮子。并发

1.使用Dubbo踩过的坑

(1)Spring Cache在Service层对消费者不起做用
缘由是:Spring容器还未加载完,就在Dubbo中暴露服务致使Cache的AOP不可用。所以须要将服务放在Spring容器加载完后再暴露。app

(2)Dubbo对方法重载支持有问题性能

若是让hessian支持调用重载方法须要isOverloadEnabled()设为false。this

2.Dubbo常见异常和错误

(1)调用超时com.alibaba.dubbo.remoting.TimeoutException异常
一般是业务处理太慢,可在服务提供方执行:jstack PID > jstack.log 分析线程都卡在哪一个方法调用上,这里就是慢的缘由。
若是不能调优性能,请将timeout设大。spa

(2)出现java.util.concurrent.RejectedExecutionException或者Thread pool exhausted线程

RejectedExecutionException表示线程池已经达到最大值,而且没有空闲连,拒绝执行了一些任务。
Thread pool exhausted一般是min和max不同大时,表示当前已建立的链接用完,进行了一次扩充,建立了新线程,但不影响运行。
缘由多是链接池不够用,请调整dubbo.properites中的:htm

// 设成同样大,减小线程池收缩开销
dubbo.service.min.thread.pool.size=200
dubbo.service.max.thread.pool.size=200

  

3.dubbo如何正确关闭Spring容器

Dubbo是经过JDK的ShutdownHook来完成优雅停机的,因此若是用户使用"kill -9 PID"等强制关闭指令,是不会执行优雅停机的,只有经过"kill PID"时,才会执行。
服务提供方中止时,先标记为不接收新请求,新请求过来时直接报错,让客户端重试其它机器。
而后,检测线程池中的线程是否正在运行,若是有,等待全部线程执行完成,除非超时,则强制关闭。
服务消费方中止时,再也不发起新的调用请求,全部新的调用在客户端即报错。
而后,检测有没有请求的响应尚未返回,等待响应返回,除非超时,则强制关闭。
设置优雅停机超时时间,缺省超时时间是10秒:(超时则强制关闭)blog

<dubbo:application ...>
    <dubbo:parameter key="shutdown.timeout" value="60000" /> <!-- 单位毫秒 -->
</dubbo:application>

看一下源码实现:rem

if ("true".equals(System.getProperty("dubbo.shutdown.hook"))) {
        Runtime.getRuntime().addShutdownHook(new Thread() {
          public void run() {
            for (Container container : this.val$containers) {
              try {
                container.stop();
                Main.logger.info("Dubbo " + container.getClass().getSimpleName() + " stopped!");
              } catch (Throwable t) {
                Main.logger.error(t.getMessage(), t);
              }
              synchronized (Main.class) {
                Main.access$102(false);
                Main.class.notify();
              }
            }
          }
        });
      }

 

Dubbo官网的 常见问题解答 了列举了不少问题。

相关文章
相关标签/搜索