結合項目里使用暴露出的問題,對並發較多的核心業務或者對請求失敗敏感的業務場景不建議使用Dubbo,
如電商的購買行為,使用Dubbo最好閱讀源碼,熟悉相關機制,或者直接自己造輪子。
1.使用Dubbo踩過的坑
(1)Spring Cache在Service層對消費者不起作用
原因是:Spring容器還未加載完,就在Dubbo中暴露服務導致Cache的AOP不可用。因此需要將服務放在Spring容器加載完后再暴露。
(2)Dubbo對方法重載支持有問題
如果讓hessian支持調用重載方法需要isOverloadEnabled()設為false。
2.Dubbo常見異常和錯誤
(1)調用超時com.alibaba.dubbo.remoting.TimeoutException異常
通常是業務處理太慢,可在服務提供方執行:jstack PID > jstack.log 分析線程都卡在哪個方法調用上,這里就是慢的原因。
如果不能調優性能,請將timeout設大。
(2)出現java.util.concurrent.RejectedExecutionException或者Thread pool exhausted
RejectedExecutionException表示線程池已經達到最大值,並且沒有空閑連,拒絕執行了一些任務。
Thread pool exhausted通常是min和max不一樣大時,表示當前已創建的連接用完,進行了一次擴充,創建了新線程,但不影響運行。
原因可能是連接池不夠用,請調整dubbo.properites中的:
// 設成一樣大,減少線程池收縮開銷 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秒:(超時則強制關閉)
<dubbo:application ...> <dubbo:parameter key="shutdown.timeout" value="60000" /> <!-- 單位毫秒 --> </dubbo:application>
看一下源碼實現:
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官網的 常見問題解答 了列舉了很多問題。