91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何排查Dubbo接口重復注銷問題

發布時間:2021-09-17 11:35:38 來源:億速云 閱讀:138 作者:柒染 欄目:web開發

本篇文章給大家分享的是有關如何排查Dubbo接口重復注銷問題,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

我在公司內負責自研的dubbo注冊中心相關工作,群里經常接到業務方反饋dubbo接口注銷報錯。經排查,確定是同一個接口調用了兩次注銷接口導致,由于我們的注冊中心注銷接口不能重復調用,調用第二次會因為實例已經注銷而報實例找不到的錯誤。

雖然這個報錯僅會打印一條錯誤日志,不影響業務,但本著 follow  through的精神,我決定還是一探究竟,更何況重復注銷也增加了應用的結束時間,影響了發布回滾速度。

問題復現

拿到業務方的dubbo版本,基于開源2.7.3內部定制的一個版本,該版本修改主要涉及安全漏洞修復以及一些業務適配,寫了個demo跑起來,然后kill,發現果然報錯了。

為了確定不是內部修改導致的問題,用開源的2.7.3版本再次測試,發現還是報錯。

同時為了確定這是一個bug,我將dubbo版本修改為2.7.7做測試,發現該版本不再報錯。

說明了重復注銷至少是開源dubbo 2.7.3的一個bug,在更高的2.7.7版本中已經被修復。

于是有了解決方案:升級dubbo,但如果這么簡單就沒有這篇文章了。

內部的dubbo已經做了修改,想升級得把改動merge到新版本,比較費勁

就算升級了內部的dubbo版本,也不可能這么快速推動業務方升級

所以應該首先找到bug是哪里導致的,其次看注冊中心的擴展是否可以修復這個問題,如果不能修復,就只能在內部的dubbo版本中修復該問題。

問題排查

懷疑ShutdownHook

由于這幾天研究過ShutdownHook(點擊查看原文跳轉《ShutdownHook原理》),第一時間懷疑ShutdownHook可能有問題。

dubbo 2.7.3代碼有關ShutdownHook的實現在DubboShutdownHook類,順著代碼梳理出如下關系

如何排查Dubbo接口重復注銷問題

看到dubbo本身和spring都注冊了ShutdownHook,更加懷疑這里是不是ShutdownHook注冊重復了。于是debug看看是否是注冊重復了,這里給一個小經驗,IntelliIDEA調試ShutdownHook執行時,要手動kill進程才會觸發debug,點IDE上的關閉按鈕不會觸發

如何排查Dubbo接口重復注銷問題

在DubboShutdownHook.doDestroy打上斷點,debug發現只會執行一次,這說明spring和dubbo的ShutdownHook只會注冊一次,這是怎么實現的呢?經過很多次測試,發現了dubbo一個很牛逼的設計。

DubboShutdownHook中有register和unregister方法,分別是注冊和注銷ShutdownHook,在這兩個方法上都打上斷點,在程序啟動時發現這樣一個有趣的執行順序:

如何排查Dubbo接口重復注銷問題

總結一下是dubbo本身注冊了ShutdownHook,但如果用到了spring框架,spring框架在初始化時注銷了dubbo注冊的ShutdownHook,這樣就只保留了spring的ShutdownHook,真是秒啊!實現的代碼只有這短短幾行

public static void addApplicationContext(ApplicationContext context) {     CONTEXTS.add(context);     if (context instanceof ConfigurableApplicationContext) {         ((ConfigurableApplicationContext) context).registerShutdownHook();         DubboShutdownHook.getDubboShutdownHook().unregister();     }     BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER); }

于是懷疑的ShutdownHook問題被證明沒有任何問題了。

從注銷堆棧繼續排查

能穩定復現的問題一定很好排查,借助IDE的debug來看兩次注銷的調用堆棧,在注冊中心擴展的unregister方法處加斷點,可以看到如下兩次來源不同的堆棧信息

如何排查Dubbo接口重復注銷問題

如何排查Dubbo接口重復注銷問題

代碼中體現是

如何排查Dubbo接口重復注銷問題

也就是說一次ShutdownHook執行,觸發了兩次注銷。

接下來就比較好排查了,一步一步debug,這里解釋下

  • AbstractRegistryFactory.destroyAll()是銷毀所有注冊中心,銷毀時會調研注冊中心的注銷接口

  • destroyProtocols是銷毀所有的protocol,注冊中心的protocol在銷毀時拿到registry,然后調用了registry的注銷接口

那么dubbo 2.7.7是如何避免這個問題的呢?

在dubbo 2.7.7的代碼中,注冊中心的protocol在銷毀時獲取注冊中心稍微增加了點代碼

如何排查Dubbo接口重復注銷問題

原來在注冊中心被銷毀后,destroyed變量被置為true,從而在registry  protocol再次獲取注冊中心時,已經拿不到了原先的注冊中心了,拿到的是一個空的注冊中心,調用注銷,自然沒有什么效果。

追溯了下github,這次PR是

https://github.com/apache/dubbo/pull/5450

這個修復在2.7.5就已經修復了

總結

  • dubbo重復注銷問題存在于2.7.0 ~  2.7.4版本,2.7.5修復,zk注冊中心不會報錯,可能無法感知,但它確實存在,也會拖慢應用的關閉速度

  • 通過追查發現,其實該問題可以在注冊中心的擴展中解決,讓registry的destroy只能被調用一次

  • 遇到無論多小的問題,有空都去鉆研下,你會收貨一些新知識,比如這次dubbo中ShutdownHook如此巧妙的設計

以上就是如何排查Dubbo接口重復注銷問題,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鹿泉市| 天全县| 石首市| 稷山县| 青河县| 理塘县| 万山特区| 毕节市| 井冈山市| 津市市| 镇宁| 海阳市| 东港市| 万山特区| 金门县| 略阳县| 平阳县| 离岛区| 商河县| 广东省| 靖边县| 彩票| 夏邑县| 巴塘县| 两当县| 莫力| 乌拉特中旗| 江阴市| 鹰潭市| 全南县| 青浦区| 临湘市| 铜山县| 太原市| 伽师县| 延边| 神农架林区| 马尔康县| 潜山县| 马边| 宿松县|