溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用事件驅(qū)動(dòng)代替定時(shí)任務(wù)的優(yōu)點(diǎn)有哪些

發(fā)布時(shí)間:2021-10-11 11:12:11 來(lái)源:億速云 閱讀:219 作者:iii 欄目:編程語(yǔ)言

這篇文章主要講解了“使用事件驅(qū)動(dòng)代替定時(shí)任務(wù)的優(yōu)點(diǎn)有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“使用事件驅(qū)動(dòng)代替定時(shí)任務(wù)的優(yōu)點(diǎn)有哪些”吧!

一、定時(shí)任務(wù)的使用

目前的系統(tǒng)設(shè)計(jì)中,定時(shí)任務(wù)是被做為很重要的組件存在的。下面我舉兩個(gè)場(chǎng)景,做為貫穿本文的例子。

1. 單據(jù)明細(xì)的匯總#

比如某家電商超市的銷售明細(xì),需要及時(shí)根據(jù)某些條件(地點(diǎn),渠道,甚至供應(yīng)商、商品等)對(duì)前一日的數(shù)據(jù)進(jìn)行分類匯總出總的銷售額。

對(duì)于這種場(chǎng)景,使用定時(shí)任務(wù)幾乎是一種思維定式:選一個(gè)凌晨系統(tǒng)比較空閑的時(shí)間,通過(guò)定時(shí)任務(wù)調(diào)度拉取全部需要匯總的數(shù)據(jù)進(jìn)行分類匯總。

2. 合同狀態(tài)的自動(dòng)變更#

比如超市和供應(yīng)商簽署返利合同,合同上面又生效時(shí)間字段和當(dāng)前狀態(tài)字段。默認(rèn)狀態(tài)是“待生效”,一旦當(dāng)前時(shí)間達(dá)到生效時(shí)間后,合同狀態(tài)變更為“已生效”。

這種場(chǎng)景也具有明顯的按照時(shí)間一刀切的特點(diǎn),所以使用定時(shí)任務(wù)幾乎也是唯一的選擇。

二、事件驅(qū)動(dòng)的使用

使用定時(shí)任務(wù)有什么不好嗎?為什么這里我要推薦事件機(jī)制呢?

下面我將用更加符合我們思維方式的基于事件觸發(fā)的邏輯來(lái)重新設(shè)計(jì)前面例子中的功能。通過(guò)不同方式的對(duì)比,你應(yīng)該能體會(huì)到他們直接明顯的差別。

1. 單據(jù)明細(xì)的匯總#

前面說(shuō)過(guò),匯總就是拿到需要處理的數(shù)據(jù),根據(jù)特定的匯總條件,將數(shù)據(jù)分組然后壓縮。

這里面有幾個(gè)關(guān)鍵信息:①需要處理的數(shù)據(jù),②根據(jù)條件分組壓縮。
所以我們先來(lái)思考第一個(gè)角度:哪些數(shù)據(jù)是需要處理的。不用想都知道,前一天還沒(méi)有匯總的數(shù)據(jù)就是需要匯總的!其實(shí)我想問(wèn)的不是這個(gè),而是如何拿到這些數(shù)據(jù)。能拿到才能處理。

很簡(jiǎn)單,使用定時(shí)任務(wù)的話,我們可以通過(guò)時(shí)間段和是否被處理過(guò)的狀態(tài)過(guò)濾出這批數(shù)據(jù)。但是如何數(shù)據(jù)量很大,比如一天有幾千萬(wàn),甚至幾十億,想要一次性撈出來(lái)然后在內(nèi)存里面分類匯總怕是有困難。
有人會(huì)說(shuō)了:不怕,處理海量數(shù)據(jù)我們有經(jīng)驗(yàn):分片處理。使用分片處理的話,我們可以通過(guò)一個(gè)基礎(chǔ)數(shù)據(jù)的接口獲取全部正在營(yíng)業(yè)的門(mén)店,比如有10萬(wàn)家,然后將它們按照某種規(guī)則分成幾組,各組分別在不同的程序?qū)嵗刑幚恚ɑ蛘咄粋€(gè)程序里順序處理)。如果是關(guān)系型數(shù)據(jù)庫(kù)的話,給門(mén)店加一個(gè)索引基本就能解決。
然后還有一個(gè)問(wèn)題需要考慮:門(mén)店每天的銷售量并不固定,甚至有些門(mén)店是一天都沒(méi)有銷售量的;而給門(mén)店分片的策略是固定的,每天哪個(gè)分片是哪些門(mén)店都是固定的。這樣導(dǎo)致的問(wèn)題是不同分片內(nèi)的數(shù)據(jù)量差異可能很大,造成的分片計(jì)算壓力也不同。

如果不使用定時(shí)任務(wù),我們還有以下方案可以選擇,而且我覺(jué)得比定時(shí)任務(wù)要好。

a. 延時(shí)匯總#

每當(dāng)一個(gè)門(mén)店向系統(tǒng)中寫(xiě)入數(shù)據(jù)的時(shí)候,系統(tǒng)需要判斷當(dāng)前數(shù)據(jù)是否是當(dāng)天的第一次寫(xiě)入。如果是第一次寫(xiě)入,則創(chuàng)建一個(gè)延時(shí)匯總事件(具體的實(shí)現(xiàn)可以是定時(shí)mq或者定時(shí)線程池,但是最好不要使用數(shù)據(jù)庫(kù),否則我們又需要一個(gè)定時(shí)任務(wù)去掃庫(kù));這樣的話,沒(méi)有業(yè)務(wù)量的門(mén)店就不會(huì)被匯總。
為了降低系統(tǒng)壓力,我們具體的延時(shí)時(shí)間也可以分列開(kāi)來(lái),不用所有門(mén)店都聚集在一起。

但是使用這種方案,相應(yīng)的一定要做補(bǔ)償。比如使用Java線程池或者akka acotr,如果系統(tǒng)重啟信息就都丟失了;如果使用mq,消息也可能消費(fèi)失敗。所以我們需要監(jiān)控和告警機(jī)制來(lái)輔助。

b. 實(shí)時(shí)匯總#

每當(dāng)數(shù)據(jù)寫(xiě)入的時(shí)候,都判斷一下該數(shù)據(jù)低匯總維度,然后寫(xiě)入?yún)R總記錄。如果匯總記錄已經(jīng)存在了,就直接更新。

這個(gè)過(guò)程主要要考慮的問(wèn)題是并發(fā)安全,我們可以使用分布式鎖或者數(shù)據(jù)庫(kù)樂(lè)觀鎖,甚至mysql的on duplicate key update(參考[https://www.manxi.info/mysqlDuplicate])。其他問(wèn)題,比如消峰,可以結(jié)合場(chǎng)景判斷。

2. 合同狀態(tài)的變更#

這種場(chǎng)景使用定時(shí)任務(wù)的標(biāo)志是按某個(gè)時(shí)間點(diǎn)所有命中某規(guī)則的記錄都要被處理。所以我們可以創(chuàng)建一個(gè)每天凌晨的定時(shí)任務(wù),判斷一下是否有合同在今天需要變成有效(或者標(biāo)記過(guò)期)。但是實(shí)際上一年365天可能只有一天這個(gè)任務(wù)能真正發(fā)揮作用,因?yàn)槠渌掌谕耆恢杏涗?—— 這不是很浪費(fèi)資源嘛!

針對(duì)這種場(chǎng)景,我們可以學(xué)習(xí)redis對(duì)過(guò)期鍵的清理策略之懶惰清理。我們不需要一種機(jī)制在精準(zhǔn)(準(zhǔn)精準(zhǔn))的時(shí)機(jī)變更合同狀態(tài),而是如果這個(gè)合同不需要被命中,那么它的狀態(tài)在數(shù)據(jù)庫(kù)中一直是之前的狀態(tài):哪怕過(guò)了生效期,我們連到數(shù)據(jù)庫(kù)中查看依然是沒(méi)有生效。只有當(dāng)業(yè)務(wù)邏輯命中這條合同的時(shí)候,返回的數(shù)據(jù)中才需要找到這種合同進(jìn)行修改。

這種方法可以有效降低系統(tǒng)邏輯中的輪空,但是查詢記錄的時(shí)候需要把前一種狀態(tài)的記錄也查找到。因?yàn)楸緛?lái)我們需要命中的合同是已經(jīng)生效的,使用懶惰策略就需要把待生效的合同也一起找到,然后從已經(jīng)生效的合同中剔除已經(jīng)過(guò)期的合同,從待生效的合同中找到已生效的合同;這時(shí)候,就需要把已過(guò)期和已生效的合同狀態(tài)都改掉。當(dāng)然我們可以使用異步邏輯去處理狀態(tài)變更,因?yàn)榧词固幚硎∫廊徊挥绊懴乱淮蔚牟樵兘Y(jié)果。

事件驅(qū)動(dòng)的好處

從上面的例子中我們可以感受到使用事件觸發(fā)機(jī)制代替定時(shí)任務(wù)實(shí)際上有利有弊。正向點(diǎn)是事件機(jī)制是按需的,有需求就來(lái),沒(méi)需要就別來(lái)。弊端是為了維護(hù)事件機(jī)制的正常運(yùn)行一般需要一套輔助邏輯:但是又有哪種邏輯不需要補(bǔ)償機(jī)制呢?只不過(guò)有些是成熟的、現(xiàn)成的,有些是需要我們重新開(kāi)發(fā)的。

從本質(zhì)上講,定時(shí)任務(wù)是一種無(wú)狀態(tài)的行為,也就不符合面向?qū)ο蟮乃枷搿6录|發(fā)是模擬了人去處理一件事的流程。
比如記錄的匯總,在有管信之前運(yùn)維人員是怎么處理的呢?如果等到第二天把前一天擠壓的單子一起處理,這就是定時(shí)任務(wù)。如果單子量很大,人工一下子處理不完,就需要多個(gè)人一起處理,這就是分布式任務(wù)。如果多個(gè)人一時(shí)半會(huì)也處理不好,需要比較長(zhǎng)的時(shí)間(人工的壓力上來(lái)了),他們可能會(huì)變通為來(lái)一單處理一單,不然一天中大部分的時(shí)間也是閑著,這樣壓力就降下來(lái)了。對(duì)于系統(tǒng)也一樣,實(shí)時(shí)處理可以有效降低系統(tǒng)壓力驟升。

實(shí)際上人工處理積壓?jiǎn)螕?jù)依然不是定時(shí)任務(wù)的原型,這樣處理僅僅是因?yàn)槿斯つ軌蛱幚淼眠^(guò)來(lái),是人性的表現(xiàn)而非模型的轉(zhuǎn)換。定時(shí)任務(wù)難以在人身上找到原型,雖然人類現(xiàn)在也在使用鬧鐘,但鬧鐘的任務(wù)是提醒而重復(fù)任務(wù)

再模擬一下合同的處理。
假設(shè)沒(méi)有管信,合同查找員估計(jì)會(huì)有幾個(gè)格子,一個(gè)放待生效的,一個(gè)放生效中的,一個(gè)放已過(guò)期的。當(dāng)需要找合同的時(shí)候,他就去前兩個(gè)格子中尋找并把已生效的從第一個(gè)格子放到第二個(gè),把已過(guò)期的從第二個(gè)挪到第三個(gè)。
那他可不可能提前挪這些合同呢?可能的,但完全沒(méi)必要:這依然是人性 —— 他太懶了。而且他今天挪過(guò)以后,可能今天一整天都沒(méi)有出現(xiàn)過(guò)需要使用合同的時(shí)候,那他為什么不在明天挪呢?所以沒(méi)有一個(gè)合適的時(shí)間去挪,干脆用的時(shí)候挪。

感謝各位的閱讀,以上就是“使用事件驅(qū)動(dòng)代替定時(shí)任務(wù)的優(yōu)點(diǎn)有哪些”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)使用事件驅(qū)動(dòng)代替定時(shí)任務(wù)的優(yōu)點(diǎn)有哪些這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI