中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

如何解決Rocketmq停機

發布時間:2021-09-17 10:37:23 來源:億速云 閱讀:142 作者:柒染 欄目:web開發

如何解決Rocketmq停機,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

1

時間追溯到2018年12月的某一天夜晚,那天我正準備上線一個需求完就回家,剛點下發布按鈕,告警就響起,我擦,難道回不了家了?看著報錯量只有一兩個,斷定只是偶發,穩住不要慌。

把剩下的機器發完,又出現了幾個同樣的錯誤,作為一名優(咸)秀(魚)程序員,這種問題必須追查到底。

如何解決Rocketmq停機

2

嫻熟地查詢到報錯日志

org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed

看著異常信息,陷入了沉思

如何解決Rocketmq停機

表面上看報錯是因為使用了已經關閉的數據源

數據源什么時候會關閉呢?只有進程被殺死的時候

莫非是應用關閉時不夠平滑?發布時會先摘除流量的呀,應該不至于呀

天色已經很晚,漫無目的地拖動日志,疲憊地尋找新線索,突然報錯日志中一個單詞引入眼簾:「rocketmq」

精神抖擻,大概知道原因了,這應用中還有個兢兢業業的rocketmq  consumer一直在消費消息,在應用關閉時,外部流量被摘除了,但沒人通知rocketmq consumer,于是它拋異常了。

如何解決Rocketmq停機

3

出于我對rocketmq不深刻甚至有點膚淺的理解,它的消費采用ack的方式,如果報錯,消息稍后還會重試,不會丟消息,而且如果消費代碼是冪等的,也不會有業務上的異常,總之這不重要,因為它也不是我寫的代碼。

瞅了一眼consumer的代碼(這里就不貼代碼了,反正貼了你也不會看),consumer注冊了一個ShutdownHook,ShutdownHook里consumer執行了shutdown來優雅地退出,并且給這個shutdownThread設置了最高優先級,然而從實踐看來,這個線程最高優先級并沒有什么卵用。

而且從《ShutdownHook原理》這篇文章中也知道ShutdownHook是并發執行的,spring容器關閉也是一個ShutdownHook,他們之前沒有先后順序。

了解原因后,第一時間想到了類似dubbo摘流的方案,吭哧吭哧寫了個優雅關閉rocketmq  cosnumer的接口,在應用關閉腳本的kill之前調用該接口,完美解決問題,趕緊下班回家,不然要猝死了。

4

夜里入睡,夢到老板讓我把所有的系統都改造掉,嚇得我一機靈。

于是第二天又重新思考這個問題,總覺得在應用里實現一個接口并在stop腳本中去調用是一件非常不優雅的事,更重要的是這也沒法復制到其他項目,我又陷入了沉思。

既然是spring容器關閉時bean的銷毀順序導致的問題,那么能不能利用spring的depend-on把順序理順了?說干就干。

起初我遇到是這樣的依賴關系:

如何解決Rocketmq停機

手把手在xml的每個bean中把depend-on關系都配上,似乎也起到了作用。

但當我打開第二個項目時,它的bean之間的依賴關系大致如下:

如何解決Rocketmq停機

好家伙,26個字母差點不夠用,當時我的心情是這樣的

所以我覺得以當前的速度,改造完所有項目可能都到9102年了。

5

又過了一段時間,在github交友網站上突然看到了rocketmq官方實現的spring-boot-starter,于是點進去看了它的實現。好家伙,看完直呼666。

官方starter實現了spring的SmartLifecycle接口,它的start方法能在所有bean初始化完成后被調用,stop方法會在bean被銷毀前調用,對rocketmq  consumer來說簡直完美。

順便還復習了一下spring容器的關閉,代碼在AbstractApplicationContext的doClose方法,這里我總結成一幅圖:

如何解決Rocketmq停機

通過上圖能看到,銷毀bean之前,有關閉lifecycle  bean和發送ContextClosedEvent兩個動作,官方starter選擇了實現LifeCycle接口的方式。

6

到這里我該給老板匯報去了,之所以rocketmq  consumer發布時不平滑是我們的使用姿勢問題,雖然對業務沒影響,但不優雅,解決方案有兩個,老板你選吧:

  • 全都換成官方starter,依賴spring-boot,官方維護,改造成本很高,

  • 監聽ContextClosedEvent來實現優雅關閉,這塊可以封裝一下,讓業務方引入依賴即可

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

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

AI

理塘县| 岳普湖县| 前郭尔| 陆良县| 鲜城| 金昌市| 定兴县| 霍城县| 山阳县| 盐津县| 宁陵县| 手机| 开封县| 宜川县| 利津县| 江达县| 武夷山市| 汉沽区| 饶河县| 沅陵县| 区。| 云阳县| 类乌齐县| 大庆市| 松江区| 增城市| 夏河县| 天祝| 蓝山县| 高要市| 嵊州市| 闻喜县| 天津市| 彭州市| 衢州市| 雅安市| 丽水市| 芒康县| 土默特右旗| 东港市| 重庆市|