天天看點

支付寶定時任務怎麼做?三層分發任務處理架構介紹

作者:阿裡開發者
本文将從單機定時排程開始,循序漸進地帶領大家了解五福定制三層分發任務處理架構。

作者 | 金盛傑(司旭)

來源 | 阿裡開發者公衆号

1、背景介紹

技術同學對定時任務肯定不陌生。定時任務一般用來定時批量進行業務處理。支付寶卡包券到期提醒、删除過期失效券,五福大促批量給使用者發放添福紅包等場景,都是通過定時任務觸發來完成的。

作者有幸參與了2023兔年五福大促的開發,主導完成了福氣樂園分會場平分5000萬大獎需求。通過學習并運用五福定制三層分發任務處理架構,最終平穩絲滑的完成了平分大獎需求任務。本文将從單機定時排程開始,循序漸進地帶領大家了解五福定制三層分發任務處理架構。

2、定時任務分類

本文将定時任務分為單機和叢集兩大類别,其中單機又分為定時排程和定時排程加批處理架構,叢集分為三層分發和五福定制三層分發任務處理架構。

2.1、單機任務

單機定時任務毫無疑問是在單台機器上運作的定時任務。在業務量級不大,沒有進行分庫分表時,往往單機定時任務即可滿足業務需求。

從複雜度上來說,單機定時任務又可分為簡單的定時排程和定時排程+批處理兩種。

1、定時排程

在Spring中可以通過@Scheduled 來啟用定時任務。觸發的方式有兩種,分别是:cron 表達式和 fixedRated類配置參數。常用的案例:

// cron表達式
@Scheduled(cron="0 0/30 9-17 * * ?") //按cron規則執行,朝九晚五工作時間内每半小時
@Scheduled(cron="0 0 12 ? * WED") //按cron規則執行,表示每個星期三中午12點

// fixedRated類配置
@Scheduled(fixedRate=5000) //上一次開始執行時間點後5秒再次執行;
@Scheduled(fixedDelay=3000) //上一次執行完畢時間點後3秒再次執行;
@Scheduled(initialDelay=1000, fixedDelay=2000) //第一次延遲1秒執行,然後在上一次執行完畢時間點後2秒再次執行;           
支付寶定時任務怎麼做?三層分發任務處理架構介紹

定時排程往往用于業務處理流程比較簡單的場景,比如定時生成簡單報表,發送通知。對于複雜耗時的場景,處理效率不高,業務高峰期會積壓大量待處理資料,影響業務。

2、定時排程+批處理

為了解決複雜耗時場景下定時排程效率不高的問題,可以引入批處理架構。定時排程與批處理架構相結合,可以大幅提高資料處理的效率,提升系統穩定性,保障業務穩定運作。

以Spring Batch批處理架構為例,任務處理流程如下:

支付寶定時任務怎麼做?三層分發任務處理架構介紹

Spring Batch批處理架構将任務拆分成多個Step,同時每個Step裡面又分為itemReader,itemProcessor, itemWriter。通過将任務分層細化,能夠讓多個階段并行處理,提高任務處理效率。批處理架構結合定時排程架構,可以在單機情況下,對大量複雜的業務進行高效的批處理。

2.2、叢集任務

在分庫分表大業務流量情況下,單機定時任務已無法滿足業務需求了,這時就産生了叢集定時任務。在支付寶技術架構下,使用者資料按照eid進行分庫分表,同時進行Zone次元的隔離。此時單機定時任務無法對全量資料做處理,于是支付寶便有了自己的分布式任務排程中間件Antscheduler,配合三層分發任務處理架構,就可以對大量資料進行定時批量處理。

1、三層分發

支付寶定時任務怎麼做?三層分發任務處理架構介紹

上圖描述了三層分發實作定時任務處理的過程:

1.Antscheduler任務排程中間件按照配置好的規則,定時往消息中心投遞消息。

2.消息中心将定時任務消息分别投遞到每個Zone中的一台機器。

3.接收到消息的機器進入三層分發的第一層,即Splitor處理流程。通常是擷取目前Zone的eid分片,比如00~24。

4.第一層Splitor處理完了之後,通過TR oneway的調用方式,在目前Zone對三層分發的第二層發起調用,即進入Loader處理流程。此時調用得到擴散,eid分片為00~24的情況下,會發起25次TR調用,即最多會進入目前Zone的25台機器進行Loader處理。

5.Loader通常是擷取傳遞過來eid分片的資料。比如一台機器的Loader接收到eid為20,則該Loader從eid為20分片的DB擷取100條待處理資料。

6.第二層Loader擷取到待處理資料後,同樣是通過TR oneway的調用方式,在目前Zone對三層分發的第三層發起調用,即進入Executor處理流程。此時調用進一步得到擴散,一個Loader擷取的100條資料,此時會發起100次TR調用,即最多會進入目前Zone的100台機器進行Executor處理。

7.Executor通常是進行真正業務處理邏輯的地方。比如對每條資料做狀态變更、發送eid次元消息等等。

三層分發能很好的将任務進行分層拆分擴散,充分利用機器資源,盡量做到負載均衡。但三層分發也存在一些缺陷,主要展現在以下幾個方面:

1.定時排程間隔和間隔内能夠處理的資料量很難完全比對。排程間隔時間太長,機器資源沒有得到有效利用,會導緻處理效率低下,任務會積壓;排程間隔時間太短,有可能會導緻資料被重複撈取處理,為此要做額外的防重複處理邏輯。

2.無法做到平滑的任務處理。由于在Loader層擷取要處理的任務數,交由Executor層執行時,并不能限制任務執行的qps,同時待處理任務數變多時,整個叢集任務的qps就變得很高,對DB和其他外圍系統來說,存在穩定性風險。

3.無法最大化利用叢集機器資源。考慮到穩定性和高可用,設計上每個Zone是有A/B分組的,每個分組都能擷取到本Zone的eid分片,是以配置Antscheduler排程規則時,通常隻會選擇Zone的A/B組中的一組開啟任務排程。三層分發内部每個層級之間的TR調用又隻能在本Zone同組内進行,A/B組之間無法進行TR調用,是以浪費了一半的機器資源。

2、五福定制三層分發

五福大促有很多業務場景都是需要通過定時任務來進行處理的,比如生肖卡提醒、AI年畫提醒,福氣樂園平分5000萬大獎。五福大促對穩定性和可用性的要求是非常高的,為了解決三層分發處理架構缺陷帶來的效率和穩定性風險,五福在三層分發基礎上做了定制化改造,改造的目标主要有兩點:

1)最大化利用叢集機器資源。做到真正的負載均衡,同時也能夠提升叢集的任務處理容量。

2)平滑的任務處理。減少任務調用的尖刺,避免對DB和外部系統造成穩定性風險。

下面分别從優化目标的兩點來進行闡述。

1、最大化利用叢集機器資源

由于三層分發預設隻會在同一個Zone的A/B組中開啟一組,導緻浪費了一半的機器。顯而易見,要最大化利用叢集機器資源,就需要讓A/B組的機器都能夠參與到任務處理當中。優化的步驟如下:

1.Antscheduler定時排程平台同時開啟A/B分組排程。

2.增加任務配置,配置的目的是讓A組的機器隻處理奇數位eid、B組的機器隻處理偶數位eid。

3.Splitor層根據任務配置,将本Zone全量eid進行分組,A組隻處理奇數位eid,B組隻處理偶數位eid。上面三步做完以後,就能讓叢集所有的機器都能參與到任務處理當中,進而最大化的利用了機器資源。

支付寶定時任務怎麼做?三層分發任務處理架構介紹

以上圖為例,Zone_01對應DB的eid分片為00~24,經過Splitor處理之後,Zone_01(A)組機器獲得任務處理的eid都是奇數位,即01、03、...23;同理,Zone_01(B)組機器獲得任務處理的eid都是偶數位,即00、02、...24。後續Loader、Executor處理都在本組内進行。通過把eid分片像A/B分組那樣進行奇/偶分組,就能讓所有機器都能夠參與到任務處理當中。

下面是eid分組的核心代碼:

/**
* 根據配置中心的dataFlag過濾
* 1、預設ALL不區分
* 2、ODD 表示僅分發奇數表号
* 3、EVEN 辨別僅分發偶數表号
*
* @param eidList
*/
public void filteByDataFlag(List<String> eidList) {
    String dataFlag = SchedulerConfigDrmUtil.getIndexFilterFlag();
    int strategy = -1;
    if (StringUtil.equalsIgnoreCase("ODD", dataFlag)) {
        strategy = 1;
    } else if (StringUtil.equalsIgnoreCase("EVEN", dataFlag)) {
        strategy = 0;
    }
    if (strategy == -1) {
        // ALL
        return;
    }
    // filter
    Iterator<String> it = eidList.iterator();
    while (it.hasNext()) {
        String str = it.next();
        int index = NumberUtils.toInt(str, -1);
        if (index % 2 != strategy) {
            it.remove();
        }
    }
}           

通過代碼可知,推送任務配置時,将A組機器的值推成“ODD”,B組機器的值推成“EVEN”,即可實作A/B組的所有機器同時執行定時任務的效果。

剩餘60%,完整内容請點選下方連結檢視:

支付寶定時任務怎麼做?三層分發任務處理架構介紹

版權聲明:本文内容由阿裡雲實名注冊使用者自發貢獻,版權歸原作者所有,阿裡雲開發者社群不擁有其著作權,亦不承擔相應法律責任。具體規則請檢視《阿裡雲開發者社群使用者服務協定》和《阿裡雲開發者社群知識産權保護指引》。如果您發現本社群中有涉嫌抄襲的内容,填寫侵權投訴表單進行舉報,一經查實,本社群将立刻删除涉嫌侵權内容。