自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Rocketmq優(yōu)雅停機往事

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

[[398013]]

本文轉(zhuǎn)載自微信公眾號「捉蟲大師」,作者捉蟲大師。轉(zhuǎn)載本文請聯(lián)系捉蟲大師公眾號。

1

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

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

[[398014]]

2

嫻熟地查詢到報錯日志

  1. 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 

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

[[398015]]

表面上看報錯是因為使用了已經(jīng)關(guān)閉的數(shù)據(jù)源

數(shù)據(jù)源什么時候會關(guān)閉呢?只有進程被殺死的時候

莫非是應(yīng)用關(guān)閉時不夠平滑?發(fā)布時會先摘除流量的呀,應(yīng)該不至于呀

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

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

3

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

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

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

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

4

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

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

既然是spring容器關(guān)閉時bean的銷毀順序?qū)е碌膯栴},那么能不能利用spring的depend-on把順序理順了?說干就干。

起初我遇到是這樣的依賴關(guān)系:

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

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

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

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

5

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

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

順便還復(fù)習了一下spring容器的關(guān)閉,代碼在AbstractApplicationContext的doClose方法,這里我總結(jié)成一幅圖:

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

6

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

  • 全都換成官方starter,依賴spring-boot,官方維護,改造成本很高,
  • 監(jiān)聽ContextClosedEvent來實現(xiàn)優(yōu)雅關(guān)閉,這塊可以封裝一下,讓業(yè)務(wù)方引入依賴即可

 

責任編輯:武曉燕 來源: 捉蟲大師
相關(guān)推薦

2021-04-19 09:37:12

RocketMQ集群版本

2023-01-30 07:41:43

2024-03-18 14:06:00

停機Spring服務(wù)器

2025-03-17 00:00:00

2025-03-11 00:55:00

Spring停機安全

2022-06-08 08:06:05

LinuxJVM內(nèi)存

2022-07-24 09:46:48

優(yōu)雅停機代碼

2024-07-22 19:31:34

2018-11-01 13:38:51

Java中斷停止

2020-08-25 10:34:22

微服務(wù)微服務(wù)架構(gòu)生產(chǎn)環(huán)境

2023-10-20 08:00:55

PodRainbow部署

2022-10-08 09:33:00

平臺中間件

2023-11-30 08:08:30

k8s優(yōu)雅停機

2021-03-26 10:38:32

云計算

2022-09-08 08:03:30

RocketMQ線程技巧

2018-11-04 08:17:41

2010-08-05 16:42:33

數(shù)據(jù)中心停機成本

2012-10-08 14:44:10

Windows往事

2019-04-30 14:17:56

中關(guān)村零售業(yè)創(chuàng)業(yè)者

2022-04-24 11:01:09

架構(gòu)數(shù)據(jù)庫專車
點贊
收藏

51CTO技術(shù)棧公眾號