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

如何設(shè)計訂單超時自動取消

開發(fā) 前端
假如少量消息丟失,我們可以通過每天凌晨跑一次任務(wù),批量將這些未處理的訂單批量取消。這種兜底行為工程實現(xiàn)簡單,同時對系統(tǒng)影響很小。

我們在美團 APP 下單,假如沒有立即支付,進入訂單詳情會顯示倒計時,如果超過支付時間,訂單就會被自動取消。

網(wǎng)上有很多八股文,很多方案其實并不太適合真實的業(yè)務(wù)場景。所以這篇文章,筆者想深入剖析如何設(shè)計訂單超時自動取消的功能,希望能帶給大家一些啟發(fā)。

圖片圖片

1 定時任務(wù)方案

首先,我們非常自然的想到定時任務(wù)的方案。

方案流程:

  1. 每隔 30 秒查詢數(shù)據(jù)庫,取出最近的 N 條未支付的訂單。
  2. 遍歷查詢出來的訂單列表,判斷當(dāng)前時間減去訂單的創(chuàng)建時間是否超過了支付超時時間,如果超時則對該訂單執(zhí)行取消操作。

定時任務(wù)方案工程實現(xiàn)相對簡單,但這種方案會間隔對數(shù)據(jù)庫造成一定的 IO 壓力。特別是當(dāng)訂單量數(shù)據(jù)量非常高時,高頻次的查詢對數(shù)據(jù)庫的性能是個不小的考驗。

定時任務(wù)方案從功能模塊角度來講,包含調(diào)度層和業(yè)務(wù)邏輯層兩部分。

圖片圖片

網(wǎng)上有很多的定時任務(wù)實現(xiàn)策略,我們可以簡單劃分為單機版和集群版。

2 定時任務(wù)方案:單機版

我們可以使用 Timer 、ScheduledEexcutorService、Quartz 非常容易的實現(xiàn)定時任務(wù)。

圖片圖片

但筆者并不推薦使用單機版的方案,舉個簡單的例子:

圖片圖片

假設(shè)我們應(yīng)用 A 通過 Quartz 調(diào)度三個定時任務(wù) A、B、C  ,當(dāng)集群部署時,可能出現(xiàn)多臺不同機器實例同時執(zhí)行任務(wù)的風(fēng)險。

此時,我們可以通過加鎖的方式適當(dāng)規(guī)避,見下圖:

圖片圖片

但這種方式并不優(yōu)雅,同時定時任務(wù)應(yīng)用內(nèi)調(diào)度層會經(jīng)??张?,我們預(yù)期是希望三個定時任務(wù) A、B、C 能均勻分布應(yīng)用 A的不同實例內(nèi)。

好,接下來,筆者會介紹親身經(jīng)歷的三種集群定時任務(wù)。

3 定時任務(wù)方案:集群版

圖片圖片

3.1 Quartz + JDBCJobStore

Quartz 可以支持集群模式,集群模式需要在數(shù)據(jù)庫中添加11張表,對業(yè)務(wù)系統(tǒng)有一定的侵入性。

圖片圖片

筆者曾經(jīng)服務(wù)的一家彩票公司,訂單調(diào)度中心就是使用 Quartz 的集群模式,實現(xiàn)日均百萬訂單的調(diào)度處理。

需要特別注意的是:

基于底層數(shù)據(jù)庫悲觀鎖的機制,Quartz 的集群模式性能并不高,假如執(zhí)行頻率高的任務(wù)數(shù)超過達(dá)到一定數(shù)量,存在性能問題。

3.1 Elastic-Job

ElasticJob 定位為輕量級無中心化解決方案,使用 jar 的形式提供分布式任務(wù)的協(xié)調(diào)服務(wù)。

ElasticJob 從本質(zhì)上來講 ,底層任務(wù)調(diào)度還是通過 Quartz ,它的優(yōu)勢在于可以依賴 Zookeeper 這個大殺器 ,將任務(wù)通過負(fù)載均衡算法分配給應(yīng)用內(nèi)的 Quartz Scheduler 容器,

舉例:應(yīng)用A有五個任務(wù)需要執(zhí)行,分別是 A,B,C,D,E。任務(wù)E需要分成四個子任務(wù),應(yīng)用部署在兩臺機器上。

圖片圖片

圖中,應(yīng)用 A 在啟動后, 5個任務(wù)通過 Zookeeper 協(xié)調(diào)后被分配到兩臺機器上,通過 Quartz Scheduler 分開執(zhí)行不同的任務(wù)。

相比 Quartz 集群模式,ElasticJob 的可擴展性更高,同時因為是本地內(nèi)存存儲 JOB,性能非常好。

但是 ElasticJob 的控制臺非常粗糙,主要原因還是基于它的實現(xiàn)機制 (Quartz +  zookeeper)。

通過控制 zookeeper 節(jié)點來間接操作應(yīng)用內(nèi)任務(wù)執(zhí)行情況,但這樣非常不靈活,所以筆者認(rèn)為 ElasticJob 更多的還是定位于框架,而不是一個調(diào)度平臺。

3.3 任務(wù)調(diào)度平臺

筆者非常認(rèn)可任務(wù)調(diào)度平臺這種模式。XXL-JOB 是一個使用最廣泛的分布式任務(wù)調(diào)度平臺。

圖片圖片

業(yè)務(wù)系統(tǒng)和調(diào)度平臺分開部署,我們在調(diào)度中心上配置應(yīng)用以及其定時任務(wù),當(dāng)任務(wù)需要執(zhí)行時,調(diào)度平臺會觸發(fā)業(yè)務(wù)系統(tǒng)的任務(wù),業(yè)務(wù)系統(tǒng)執(zhí)行完任務(wù)之后,反饋給調(diào)度平臺任務(wù)執(zhí)行的結(jié)果。

業(yè)務(wù)系統(tǒng)和調(diào)度平臺都可以水平擴展實現(xiàn)高可用,同時在調(diào)度平臺可以配置靈活的調(diào)度策略(比如重試機制、廣播模式等)。

XXL-JOB  并不完美,因為底層依然是基于數(shù)據(jù)庫悲觀鎖的機制,雖然通過時間輪的方式做了一定程度的優(yōu)化,但依然會有性能瓶頸。

很多公司比如神州專車、美團都有自己自研的任務(wù)調(diào)度平臺。這種模式非常適合多團隊協(xié)作,便于大規(guī)模調(diào)度任務(wù)的統(tǒng)一管理。

4 延時消息方案

延時消息是一種非常優(yōu)雅的模式。訂單服務(wù)生成訂單后,發(fā)送一條延時消息到消息隊列。消息隊列在消息到達(dá)支付過期時間時,將消息投遞給消費者,消費者收到消息之后,判斷訂單狀態(tài)是否為已支付,假如未支付,則執(zhí)行取消訂單的邏輯。

圖片圖片

4.1 消息隊列 RocketMQ

RocketMQ 4.X 生產(chǎn)者發(fā)送延遲消息代碼如下:

Message msg = new Message();
msg.setTopic("TopicA");
msg.setTags("Tag");
msg.setBody("this is a delay message".getBytes());
//設(shè)置延遲level為5,對應(yīng)延遲1分鐘
msg.setDelayTimeLevel(5);
producer.send(msg);

RocketMQ 4.X 版本默認(rèn)支持 18 個 level 的延遲消息, 通過 broker 端的 messageDelayLevel 配置項確定的。

圖片圖片

RocketMQ 5.X 版本支持任意時刻延遲消息,客戶端在構(gòu)造消息時提供了 3 個 API 來指定延遲時間或定時時間。

圖片圖片

假如技術(shù)團隊基礎(chǔ)架構(gòu)能力很強,筆者非常推薦使用 RocketMQ 5.X 的延遲消息功能。

4.2 自研延遲服務(wù)

基于 RocketMQ 4 內(nèi)置的延遲消息只能支持幾個固定的延遲級別,快手、滴滴開發(fā)了單獨的 Delay Server 來調(diào)度延遲消息。

圖片圖片

上圖這個結(jié)構(gòu)沒有直接將延遲消息發(fā)到 Delay Server,而是更換 Topic 以后存入 RocketMQ。這樣的好處是可以復(fù)用現(xiàn)有的消息發(fā)送接口(以及上面的所有擴展能力)。對業(yè)務(wù)來說,只需要在構(gòu)造消息的時候額外指定一個延遲時間字段即可,其它用法都不變。

自研單獨的  Delay Server 不僅可以適配 RocketMQ 4.X , 也可以適配 Kafka ,同時,也可以具有非常高的性能,說實話,這個是一個非常實用且靈活的方案。

4.3 Redis 延遲隊列

Redis 延遲隊列是一個輕量級的解決方案,開源成熟的實現(xiàn)是 Redission 。

圖片圖片

圖中,我們定義兩個集合:

1、zset 集合

生產(chǎn)者將任務(wù)信息發(fā)送到 zset 集合,value 是任務(wù)編號,score 是任務(wù)執(zhí)行時間戳。

2、list 集合

守護線程檢測  zset 集合中到期的任務(wù),若任務(wù)到期,將任務(wù)編號轉(zhuǎn)移到 list 集合 , 消費者從 list 集合彈出任務(wù),并執(zhí)行任務(wù)邏輯。

筆者需要強調(diào)的是:

Redis 雖然可以實現(xiàn)延遲消息的功能,但 Redis 并不是真正意義上的消息隊列,在使用過程中還是有小概率會丟失消息。

5 最佳實踐

5.1 并發(fā)口訣:一鎖二判三更新

不管我們使用定時任務(wù)還是延遲消息時,不可避免的會遇到并發(fā)執(zhí)行任務(wù)的情況 (比如重復(fù)消費、調(diào)度重試等)。

當(dāng)我們執(zhí)行任務(wù)時,我們可以按照一鎖二判三更新這個口訣來處理。

  1. 鎖定當(dāng)前需要處理的訂單。
  2. 判斷訂單是否已經(jīng)更新過對應(yīng)狀態(tài)了
  3. 如果訂單之前沒有更新過狀態(tài)了,可以更新并完成相關(guān)業(yè)務(wù)邏輯,否則本次不能更新,也不能完成業(yè)務(wù)邏輯。
  4. 釋放當(dāng)前訂單的鎖。

圖片圖片

偽代碼偽代碼

5.2 兜底意識 + 配置監(jiān)控

雖然我們提到了很多的實現(xiàn)策略,現(xiàn)實實戰(zhàn)時依然容易出現(xiàn)問題,比如不合理的操作導(dǎo)致消息丟失。

因此,我們應(yīng)該具備兜底意識。

假如少量消息丟失,我們可以通過每天凌晨跑一次任務(wù),批量將這些未處理的訂單批量取消。這種兜底行為工程實現(xiàn)簡單,同時對系統(tǒng)影響很小。

還有一點,就是配置監(jiān)控。

筆者曾經(jīng)自研過任務(wù)調(diào)度系統(tǒng),應(yīng)用 A 接入后,從控制臺發(fā)現(xiàn)每隔 2 個小時調(diào)度應(yīng)用 A 的任務(wù)時,經(jīng)常發(fā)生超時,通過分析,發(fā)現(xiàn)應(yīng)用 A 線程出現(xiàn)了死鎖。

這種問題出現(xiàn)的幾率非常高,因此配置監(jiān)控特別要必要。

對業(yè)務(wù)系統(tǒng)來講,監(jiān)控分為兩個層面:系統(tǒng)監(jiān)控和業(yè)務(wù)監(jiān)控。

  • 系統(tǒng)監(jiān)控

在條件允許的情況下,建議關(guān)注性能監(jiān)控,方法可用性監(jiān)控,方法調(diào)用次數(shù)監(jiān)控這三大類。

性能監(jiān)控性能監(jiān)控

上圖是性能監(jiān)控的示例圖,性能監(jiān)控不同時間段性能分布,實時統(tǒng)計 TP99、TP999 、AVG 、MAX 等維度指標(biāo),這也是性能調(diào)優(yōu)的重點關(guān)注對象。

  • 業(yè)務(wù)監(jiān)控

業(yè)務(wù)監(jiān)控功能是從業(yè)務(wù)角度出發(fā),各個應(yīng)用系統(tǒng)需要從業(yè)務(wù)層面進行哪些監(jiān)控,以及提供怎樣的業(yè)務(wù)層面的監(jiān)控功能支持業(yè)務(wù)相關(guān)的應(yīng)用系統(tǒng)。

具體就是對業(yè)務(wù)數(shù)據(jù),業(yè)務(wù)功能進行監(jiān)控,實時收集業(yè)務(wù)流程的數(shù)據(jù),并根據(jù)設(shè)置的策略對業(yè)務(wù)流程中不符合預(yù)期的部分進行預(yù)警和報警,并對收集到業(yè)務(wù)監(jiān)控數(shù)據(jù)進行集中統(tǒng)一的存儲和各種方式進行展示。

比如訂單系統(tǒng)中有一個定時結(jié)算的服務(wù),每兩分鐘執(zhí)行一次。我們可以在定時任務(wù) JOB 中添加埋點,并配置業(yè)務(wù)監(jiān)控,假如十分鐘該定時任務(wù)沒有執(zhí)行,則發(fā)送郵件,短信給相關(guān)負(fù)責(zé)人。

6 總結(jié)

這篇文章,筆者總結(jié)了訂單超時自動取消方案的兩種流派:定時任務(wù)和延遲消息。

1、定時任務(wù)

定時任務(wù)實現(xiàn)策略,我們可以簡單劃分為單機版和集群版。

筆者并不認(rèn)可單機版,背八股文當(dāng)然可以,訂單自動取消這個業(yè)務(wù)場景,生產(chǎn)環(huán)境還是要慎重。

集群版有三種方式:Quartz + JDBCJobStore、ElasticJob 、XXL-JOB 。

每種方式各有優(yōu)缺點,筆者更傾向于任務(wù)調(diào)度平臺 XXL-JOB 這種方式。

2、延遲消息

延時消息是一種非常優(yōu)雅的模式。本文介紹了三種方式:消息隊列 RocketMQ、自研延遲服務(wù)、Redis 延遲隊列。

假如技術(shù)團隊基礎(chǔ)架構(gòu)能力很強,筆者推薦使用 RocketMQ 或者自研延遲服務(wù)。

假如技術(shù)團隊僅僅想用輕量級的實現(xiàn),可以選擇 Redis 延遲隊列。

不管是使用定時任務(wù)還是延遲消息,架構(gòu)的穩(wěn)定性還需要注意如下兩點:

1、并發(fā)口訣:一鎖二判三更新 ;

2、兜底意識 + 配置監(jiān)控。

責(zé)任編輯:武曉燕 來源: 勇哥Java實戰(zhàn)
相關(guān)推薦

2023-01-30 08:12:53

訂單超時自動取消延長訂單

2022-12-01 08:25:03

訂單超時定時任務(wù)

2024-12-20 08:20:46

2024-11-05 16:58:21

RabbitMQ訂單超時取消延遲隊列

2024-10-16 09:29:30

RabbitMQ延遲隊列

2024-08-27 13:43:38

Spring系統(tǒng)業(yè)務(wù)

2024-03-28 08:32:10

美團關(guān)閉訂單輪訓(xùn)

2021-09-07 08:14:26

訂單超時未支付

2020-10-21 09:25:01

互聯(lián)網(wǎng)訂單自動關(guān)閉

2023-10-09 16:35:19

方案Spring支付

2025-05-09 09:31:31

支付訂單Timer

2023-11-20 08:39:24

Spring定時任務(wù)

2023-11-27 08:15:26

Spring訂單取消

2024-09-12 15:43:46

C#代碼后端

2009-12-08 16:37:33

華為20億美元訂單

2024-10-14 12:05:56

2022-03-02 15:14:09

訂單計時器持久化

2019-09-19 11:52:59

Linux腳本語言Vim

2019-08-23 08:09:18

訂單號生成數(shù)據(jù)庫ID

2025-05-06 00:12:10

點贊
收藏

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

主站蜘蛛池模板: 色视频在线观看 | 一区二区三区免费在线观看 | 91不卡 | 精品国产视频 | 国产特黄一级 | 亚洲国产高清在线观看 | 波多野结衣先锋影音 | 久久久久久久电影 | 精品videossex高潮汇编 | 精精国产视频 | 涩色视频在线观看 | 亚洲欧美视频一区 | 久久久精品视频一区二区三区 | 色伊人久久 | 免费国产视频 | 欧美伊人| 日韩国产一区二区三区 | 日韩精品一区二区三区在线播放 | 免费看爱爱视频 | 欧美日韩国产精品一区 | 中文字幕在线电影观看 | 亚洲色片网站 | 精品国产乱码久久久久久果冻传媒 | 日韩欧美在线观看一区 | 综合久久99 | 欧美精品91爱爱 | 羞羞视频在线观看网站 | 一区二区在线免费观看 | 91传媒在线观看 | 中文字幕精| 成年人在线观看 | 国产精品免费一区二区三区 | 午夜私人影院在线观看 | 国产午夜精品福利 | 国产高清在线精品一区二区三区 | 一级免费毛片 | 中文字幕在线一区 | 欧美成人手机在线 | 日韩午夜影院 | 欧美日韩视频在线 | 久久久久久国产精品 |