成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

排查Dubbo接口重復注銷問題,我發現了一個巧妙的設計

開發 前端
我在公司內負責自研的dubbo注冊中心相關工作,群里經常接到業務方反饋dubbo接口注銷報錯。

 [[396584]]

本文轉載自微信公眾號「捉蟲大師」,作者捉蟲大師。轉載本文請聯系捉蟲大師公眾號。

背景

我在公司內負責自研的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本身和spring都注冊了ShutdownHook,更加懷疑這里是不是ShutdownHook注冊重復了。于是debug看看是否是注冊重復了,這里給一個小經驗,IntelliIDEA調試ShutdownHook執行時,要手動kill進程才會觸發debug,點IDE上的關閉按鈕不會觸發

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

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

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

  1. public static void addApplicationContext(ApplicationContext context) { 
  2.     CONTEXTS.add(context); 
  3.     if (context instanceof ConfigurableApplicationContext) { 
  4.         ((ConfigurableApplicationContext) context).registerShutdownHook(); 
  5.         DubboShutdownHook.getDubboShutdownHook().unregister(); 
  6.     } 
  7.     BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER); 

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

從注銷堆棧繼續排查

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

代碼中體現是

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

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

  • AbstractRegistryFactory.destroyAll()是銷毀所有注冊中心,銷毀時會調研注冊中心的注銷接口
  • destroyProtocols是銷毀所有的protocol,注冊中心的protocol在銷毀時拿到registry,然后調用了registry的注銷接口

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

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

原來在注冊中心被銷毀后,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如此巧妙的設計

 

責任編輯:武曉燕 來源: 捉蟲大師
相關推薦

2024-05-20 08:25:55

2021-10-29 11:45:26

Python代碼Python 3.

2022-11-30 09:18:51

JavaMyBatisMQ

2025-05-19 10:04:48

2021-04-22 07:47:47

JavaJDKMYSQL

2023-05-17 00:22:15

2021-06-02 08:00:57

WebAsyncTas項目異步

2020-05-18 08:42:23

CSS背景圖像前端開發

2022-04-06 08:47:03

Dubbo服務協議

2019-01-14 11:10:43

機器學習人工智能計算機

2025-06-04 08:10:59

2023-02-26 01:02:22

2021-12-29 19:20:41

數據GitHub服務器

2023-06-05 08:22:20

2020-04-01 08:40:44

Vue.jsweb開發

2024-06-06 08:46:37

2024-11-08 14:18:38

2024-06-03 11:43:55

2022-06-08 08:14:27

Dubbo數據包源代碼

2022-06-10 13:03:44

接口重試while
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美黄色免费网站 | 91精品久久久久久久久99蜜臂 | 国产视频福利一区 | 精品日韩在线 | 91av在线影院| 亚洲精品一区二区三区蜜桃久 | 亚洲精品视频二区 | 国产精品入口麻豆www | 免费在线看黄 | 伊人精品视频 | 蜜桃av一区二区三区 | 国产精品精品久久久 | 亚洲免费网站 | 亚洲免费在线观看视频 | 美女在线观看国产 | 国产乱码精品一区二区三区五月婷 | 日韩欧美国产不卡 | 中文字幕日本一区二区 | 欧美国产一区二区三区 | 亚洲视频二区 | 亚洲免费视频一区二区 | 99热这里都是精品 | 伊人网国产 | 欧美 日韩 综合 | 天堂网中文字幕在线观看 | 日韩一区二区三区在线看 | 久久一区视频 | 碰碰视频 | 国产精品一区二区福利视频 | 免费国产一区二区 | av日韩精品| 国产一区2区| 午夜影院污 | 国产在线视频一区二区董小宛性色 | 欧美日韩18| 亚洲国产一区二区三区 | 日韩在线中文 | 久久精品国产久精国产 | 99热这里| 91在线视频免费观看 | 99精品免费久久久久久日本 |