掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
本文轉(zhuǎn)載自微信公眾號(hào)「bugstack蟲洞?!?,作者小傅哥。轉(zhuǎn)載本文請(qǐng)聯(lián)系bugstack蟲洞棧公眾號(hào)。

10年積累的網(wǎng)站制作、網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有微山免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
不卷了,能用就行!
哈哈哈,說好的不卷了,能湊活用就行了。但每次接到新需求時(shí)都手癢,想結(jié)合著上一次的架構(gòu)設(shè)計(jì)和落地經(jīng)驗(yàn),在這一次需求上在迭代更新,或者找到完全顛覆之前的更優(yōu)方案。卷完代碼的那一刻總是神清氣爽
其實(shí)大部分喜歡寫代碼的一類純粹碼農(nóng),都是比較卷的,就比如一個(gè)需求在實(shí)現(xiàn)上是能用大概是P5、如果這個(gè)做出來的功能不只是能用還非常好用是P6、除了好用還凝練共性需求開發(fā)成通用的組件服務(wù)是P7。每一個(gè)成長過來的碼農(nóng),都是在造輪子的路上一次次驗(yàn)證自己的想法和加以實(shí)踐,絕對(duì)不是一篇篇的八股文就能累出來一個(gè)高級(jí)的技術(shù)大牛。
當(dāng)我們的實(shí)際業(yè)務(wù)需求場景中,有一些活動(dòng)開始前的狀態(tài)變更、訂單結(jié)算后的T+1對(duì)賬、貸款單息費(fèi)的產(chǎn)生,都是需要使用到延遲任務(wù)來進(jìn)行觸達(dá)。實(shí)際的操作一般會(huì)有 Quartz、Schedule 來對(duì)你的庫表數(shù)據(jù)進(jìn)行定時(shí)掃描和處理,當(dāng)條件滿足后做數(shù)據(jù)狀態(tài)的變更或者產(chǎn)生新的數(shù)據(jù)插入到表中。
這樣一個(gè)簡單的需求就是延遲任務(wù)最初需求,如果需求前期內(nèi)容較少、使用方不多,可能在實(shí)際開發(fā)中就只是一個(gè)單臺(tái)機(jī)器直接對(duì)著表一頓輪訓(xùn)就完事了。但隨著業(yè)務(wù)需求的發(fā)展和功能的復(fù)雜度提升,往往反饋到研發(fā)設(shè)計(jì)和實(shí)現(xiàn),就不那么簡單了,比如:你需要保障盡可能低延遲完成較大規(guī)模的數(shù)據(jù)量掃描處理,否則就像貸款單息費(fèi)的產(chǎn)生,已經(jīng)到了第二天用戶還沒看到自己的息費(fèi)信息或者是還款后的重新對(duì)賬,可能就這個(gè)時(shí)候就要產(chǎn)生客訴了。
那么,類似這樣的場景該如何設(shè)計(jì)呢?
通常的任務(wù)中心處理流程主要,主要是由定時(shí)任務(wù)掃描任務(wù)庫表,把即將達(dá)到超時(shí)時(shí)間的任務(wù)信息掃描到處理隊(duì)列(內(nèi)存/MQ消息),再由業(yè)務(wù)系統(tǒng)進(jìn)行處理任務(wù),處理完成后更新庫表中的任務(wù)狀態(tài)。
高延時(shí)任務(wù)調(diào)度
海量數(shù)據(jù)規(guī)模較大的任務(wù)列表數(shù)據(jù),在分庫分表下該需要快速掃描。
任務(wù)掃描服務(wù)與業(yè)務(wù)邏輯處理,耦合在一起,不具有通用性和復(fù)用性。
細(xì)分任務(wù)體系有些是需要低延遲處理的,不能等待過長時(shí)間。
除了一些較小的狀態(tài)變更場景,例如在各自業(yè)務(wù)的庫表中,就包含了一個(gè)狀態(tài)字段,這個(gè)字段一方面有程序邏輯處理變更的狀態(tài),也有到達(dá)指定到期時(shí)間后由任務(wù)服務(wù)自動(dòng)變更處理的操作,一般這類功能,直接設(shè)計(jì)到自己的庫表中即可。
那么還有一些較大也較為頻繁使用的場景,如果都是在每個(gè)系統(tǒng)的各自所需的N多個(gè)表中,都添加這樣的字段進(jìn)行維護(hù),就顯得非常冗余了,也不那么易于維護(hù)。所以針對(duì)這樣的場景就很適合做一個(gè)通用的任務(wù)延時(shí)系統(tǒng),各業(yè)務(wù)系統(tǒng)把需要被延時(shí)執(zhí)行的動(dòng)作提交到延時(shí)系統(tǒng)中,再有延時(shí)系統(tǒng)在指定時(shí)間下進(jìn)行回調(diào),回調(diào)的動(dòng)作可以是接口或者M(jìn)Q消息進(jìn)行觸達(dá)。例如可以設(shè)計(jì)這樣一個(gè)任務(wù)調(diào)度表:
任務(wù)調(diào)度庫表設(shè)計(jì)
抽取的任務(wù)調(diào)度表,主要是拿到什么任務(wù),在什么時(shí)間發(fā)起動(dòng)作,具體的動(dòng)作處理仍交給業(yè)務(wù)工程處理。
大批量的各自業(yè)務(wù)的任務(wù)進(jìn)行集中處理,則需要設(shè)計(jì)一個(gè)分庫分表,滿足于后續(xù)業(yè)務(wù)體量的增長。
門牌號(hào)設(shè)計(jì),針對(duì)一張表的掃描,如果數(shù)據(jù)量較大,又不希望只是一個(gè)任務(wù)掃描一個(gè)表,可以多個(gè)任務(wù)掃描一個(gè)表,加到掃描的體量。這個(gè)時(shí)候就需要一個(gè)門牌號(hào)來隔離不同任務(wù)掃描的范圍,避免掃描出重復(fù)的任務(wù)數(shù)據(jù)。
低延遲處理方案,是在任務(wù)表方式的基礎(chǔ)上,新增加的時(shí)間把控處理。它可以把即將到期的前一段時(shí)間的任務(wù),放置到 Redis 集群隊(duì)里中,在消費(fèi)的時(shí)候再從隊(duì)列中 pop 出來,這樣可以更快的接近任務(wù)的處理時(shí)效,避免因?yàn)閽邘扉g隔較大延遲任務(wù)執(zhí)行。
任務(wù)處理流程
Redis 消費(fèi)隊(duì)列
Redis 消費(fèi)隊(duì)列
@Test
public void test_delay_queue() throws InterruptedException {
RBlockingQueue
2022-02-13 WARN 204760 --- [ Finalizer] i.l.c.resource.DefaultClientResources : io.lettuce.core.resource.DefaultClientResources was not shut down properly, shutdown() was not called before it's garbage-collected. Call shutdown() or shutdown(long,long,TimeUnit)
測試1
測試2
測試3
測試4
測試5
Process finished with exit code -1

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流