當前位置: 妍妍網 > 碼農

百萬級任務重試框架 Fast-Retry

2024-06-06碼農

架構師(JiaGouX)

我們都是架構師!
架構未來,你來不來?

前言

假設你的系統裏有100萬個使用者,然後你要輪詢重試的獲取每個使用者的身份資訊, 如果你還在使用SpringRetry和GuavaRetry 之類的這種單任務的同步重試框架,那你可能到猴年馬月也處理不完, 即使加再多的機器和執行緒也是杯水車薪, 而Fast-Retry正是為這種場景而生

Fast-Retry

一個高效能的多工重試框架,支持百萬級任務的異步重試、以及支持編程式和註解聲明式等多種使用方式、 也支持自訂結果重試邏輯。

What is this?

與主流的Spring-Retry, Guava-Retry等單任務同步重試框架不同,Fast-Retry是一個支持異步重試框架,支持異步任務的重試、超時等待、回呼。Spring-Retry, Guava-Retry均無法支持大批次任務的重試,即使加入執行緒池也無法解決,因為實際每個重試任務都是單獨的同步邏輯,然後會會占用過多執行緒資源導致大量任務在等待處理,隨著任務數的增加,系統吞吐量大大降低,效能指數級降低,而Fast-Retry在異步重試下的效能是前者的指數倍。下圖是三者的效能對比

  • 測試執行緒池: 8個固定執行緒

  • 單個任務邏輯: 輪詢5次,隔2秒重試一次,總耗時10秒

  • 未測預計公式: 當我們使用執行緒池的時候, 一般執行緒池中 總任務處理耗時 = 任務數/並行度 x 單個任務重試耗時

  • 可以看到即使是處理100萬個任務,Fast-Retry的效能也比Spring-Retry和Guava-Retry處理在50個任務時的效能還要快的多的多屬實降維打擊,這麽快的秘密在於除了是異步,重要的是當別人在重試間隔裏休息的時候,Fast-Retry還在不停忙命的工作著。即使拋開效能不談, SpringRetry使用繁瑣,不支持根據結果的進行重試,GuavaRetry雖然支持,但是又沒有提供註解聲明式的使用。

    快速開始

    引入依賴

    xml復制程式碼 <dependency>
    <groupId>io.github.burukeyou</groupId>
    <artifactId>fast-retry-all</artifactId>
    <version>0.2.0</version>
    </dependency>

    有以下三種方式去構建我們的重試任務

    使用重試佇列

    RetryTask就是可以配置我們重試任務的一些邏輯,比如怎麽重試,怎麽獲取重試結果,隔多久後重試,在什麽情況下重試。它可以幫助我們更加自由的去構建重試任務的邏輯。但如果只是簡單使用,強烈建議使用FastRetryBuilder 或者 @FastRetry註解 RetryQueue就是一個執行和排程我們重試任務的核心角色,其在使用上與執行緒池的API方法基本一致

    ExecutorService executorService = Executors.newFixedThreadPool(8);
    RetryQueue queue =newFastRetryQueue(executorService);
    RetryTask<String> task =newRetryTask<String>() {
    int result =0 ;
    // 下一次重試的間隔
    @Override
    public long waitRetryTime() {
    return2000;
    }
    // 執行重試,每次重試回呼此方法
    @Override
    public boolean retry() {
    return++result <5;
    }
    // 獲取重試結果
    @Override
    publicStringgetResult() {
    return result +"";
    }
    };
    CompletableFuture<String> future = queue.submit(task);
    log.info("任務結束 結果:{}",future.get());

    使用FastRetryBuilder

    底層還是使用的RetryQueue去處理, 只是幫我們簡化了構建RetryTask的邏輯

    RetryResultPolicy<String> resultPolicy = result -> result.equals("444");
    FastRetryer<String> retryer = FastRetryBuilder.<String>builder()
    .attemptMaxTimes(3)
    .waitRetryTime(3, TimeUnit.SECONDS)
    .retryIfException(true)
    .retryIfExceptionOfType(TimeoutException. class)
    .exceptionRecover(true)
    .resultPolicy(resultPolicy)
    .build();
    CompletableFuture<String> future = retryer.submit(() -> {
    log.info("重試");
    //throw new Exception("test");
    //int i = 1/0;
    if (0<10){
    thrownewTimeoutException("test");
    }
    return"444";
    });
    String o = future.get();
    log.info("結果{}", o);

    使用@FastRetry註解

    底層還是使用的RetryQueue去處理, 只是幫我們簡化了構建RetryTask的邏輯,並且與Spring進行整合能對Spring的bean標記了FastRetry註解的方法進行代理, 提供了重試任務註解聲明式的使用方式:

  • 依賴Spring環境,所以需要在Spring配置類加上@EnableFastRetry註解啟用配置 , 這個@FastRetry註解的使用才會生效

  • 如果將結果型別使用CompletableFuture包裝,自動進行異步輪詢返回,否則同步阻塞等待重試結果。(推薦)

  • 下面定義等價於 RetryQueue.execute方法

    // 如果發生異常,每隔兩秒重試一次
    @FastRetry(retryWait = @RetryWait(delay =2))
    publicStringretryTask(){
    return"success";
    }

    下面定義等價於 RetryQueue.submit方法,支持異步輪詢

    @FastRetry(retryWait = @RetryWait(delay =2))
    public CompletableFuture<String>retryTask(){
    return CompletableFuture.completedFuture("success");
    }

    自訂重試註解

    如果不喜歡或者需要更加通用化的貼近業務的重試註解,提供一些預設的參數和處理邏輯,可以自行定義一個重試註解並標記上@FastRetry並指定factory,然後實作AnnotationRetryTaskFactory介面實作自己的構建重試任務的邏輯即可。@FastRetry預設實作就是:FastRetryAnnotationRetryTaskFactory

    使用建議

    無論是使用以上哪種方式去構建你的重試任務,都建議使用異步重試的方法,即返回結果是CompletableFuture的方法, 然後使用CompletableFuture的whenComplete方法去等待異步重試任務的執行結果。

    其他


  • github計畫地址 :
    https://github.com/burukeYou/fast-retry
    具體使用案例見fast-retry-demo模組

  • maven倉庫地址:

  • https://central.sonatype.com/artifact/io.github.burukeyou/fast-retry-all


    還在叠代中,第一個版本主要專註於多重試任務的處理, 還需要什麽好玩的功能和特征請留下你的意見感謝。覺得有用或者能學到點什麽可以star下哈哈


    如喜歡本文,請點選右上角,把文章分享到朋友圈
    如有想了解學習的技術點,請留言給若飛安排分享

    因公眾號更改推播規則,請點「在看」並加「星標」 第一時間獲取精彩技術分享

    ·END·

    相關閱讀:

    作者:李白的手機

    來源:https://juejin.cn/post/7337989768637939739

    版權申明:內容來源網路,僅供學習研究,版權歸原創者所有。如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝!

    架構師

    我們都是架構師!

    關註 架構師(JiaGouX),添加「星標」

    獲取每天技術幹貨,一起成為牛逼架構師

    技術群請 加若飛: 1321113940 進架構師群

    投稿、合作、版權等信箱: [email protected]