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官網的 常見問題解答 了列舉了不少問題。

相關文章
相關標籤/搜索