guava-retrying3 學(xué)習(xí)

使用場景

做自動化場景,對于一些數(shù)據(jù)統(tǒng)計祖凫,有時數(shù)據(jù)同步更新會遇到延遲的場景琼蚯,延時的時間可能不確定,此時惠况,如果用 sleep 一定時間的話遭庶,可能會造成時間的浪費。那么有什么方法了避免呢稠屠,比如使用重試機制峦睡,設(shè)置重試的時間和重試的次數(shù),當(dāng)獲取不到數(shù)據(jù)時根據(jù)預(yù)定的時間來重新請求接口权埠。

重試的實現(xiàn)的要素

  • 重試觸發(fā)時機
  • 什么條件去停止
  • 重試等待時間
  • 重試停止條件
  • 接口請求時間限制
  • 如果結(jié)束
  • 重試時的監(jiān)聽

guava-retrying 策略介紹

  • ** retryIfException() **: 當(dāng)發(fā)生任何異常時觸發(fā)重試榨了。
  • ** retryIfExceptionOfType(Class<? extends Throwable> exceptionType) ** : 當(dāng)發(fā)生指定類型的異常時觸發(fā)重試。
  • ** retryIfRuntimeException() **:當(dāng)發(fā)生 RuntimeException 或其子類異常時觸發(fā)重試攘蔽。
  • ** retryIfResult(Predicate<R> resultPredicate) ** :根據(jù)返回結(jié)果的條件觸發(fā)重試龙屉。可以使用自定義的 Predicate 對返回結(jié)果進行判斷满俗。
  • ** retryIfException(Predicate<Throwable> exceptionPredicate) **:根據(jù)異常的條件觸發(fā)重試转捕。可以使用自定義的 Predicate 對異常進行判斷漫雷。
  • ** withStopStrategy(StopStrategy stopStrategy) **:配置停止策略瓜富,指定在何時停止重試。常用的停止策略包括:
  • ** StopStrategies.stopAfterAttempt(int maxAttempts) **:在達到最大嘗試次數(shù)后停止重試降盹。
  • ** StopStrategies.neverStop() **:永不停止重試与柑,會一直進行重試
  • ** withWaitStrategy(WaitStrategy waitStrategy) **:配置等待策略谤辜,指定每次重試之間的等待時間。常用的等待策略包括:
    • ** WaitStrategies.fixedWait(long sleepTime, TimeUnit timeUnit) **:固定等待時間价捧,每次重試之間等待指定的時間間隔丑念。
    • ** WaitStrategies.randomWait(long minimumTime, long maximumTime, TimeUnit timeUnit) **:隨機等待時間,每次重試之間等待隨機的時間間隔结蟋。
  • ** withAttemptTimeLimiter(AttemptTimeLimiter<V> attemptTimeLimiter) **:配置重試時間限制器脯倚,用于限制每次重試的時間∏妒海可以使用 FixedAttemptTimeLimit推正、ExponentialAttemptTimeLimit 或自定義的時間限制器。
  • ** withRetryListener(RetryListener retryListener) **:添加重試監(jiān)聽器宝惰,用于在重試過程中觸發(fā)相應(yīng)的事件植榕。可以實現(xiàn) RetryListener 接口自定義監(jiān)聽器
  • ** withBlockStrategy() **:方法用于配置阻塞策略尼夺,指定在進行重試時的阻塞行為尊残。阻塞策略定義了在重試之間是否需要進行阻塞等待,以及等待的方式和時長

構(gòu)造一個 Retryer

Retryer<T> retryer = RetryerBuilder.<T>newBuilder()
                .retryIfException()
                // 自定義重試條件
                .retryIfExceptionOfType(NeedRetryException.class)
                //停止策略淤堵,最大嘗試請求寝衫, attemptNumber次
                .withStopStrategy(StopStrategies.stopAfterAttempt(attemptNumber))
                //等待策略,每次請求間隔1s
                .withWaitStrategy(WaitStrategies.fixedWait(sleepTime, TimeUnit.SECONDS))
                //嘗試請求時間限制拐邪,不能超過 taskTime
                .withAttemptTimeLimiter(new FixedAttemptTimeLimit(taskTime, TimeUnit.SECONDS, Executors.newCachedThreadPool()))
                //方法用于配置阻塞策略慰毅,指定在進行重試時的阻塞行為
                .withBlockStrategy(spinBlockStrategy)
                //重試過程的監(jiān)聽策略,打印了嘗試的次數(shù)
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        log.info("嘗試次數(shù) " + attempt.getAttemptNumber());
                    }
                })
                .build();

嘗試定義一個方法庙睡,使用 Callable 接口作為參數(shù)傳入一個執(zhí)行的任務(wù)

 public static <T> T retry(Callable<T> task, int attemptNumber, int sleepTime, int taskTime) throws Throwable {
        SpinBlockStrategy spinBlockStrategy = new SpinBlockStrategy();
        spinBlockStrategy.block(1);
        Retryer<T> retryer = RetryerBuilder.<T>newBuilder()
                .retryIfException()
                // 自定義重試條件
                .retryIfExceptionOfType(NeedRetryException.class)
                //停止策略事富,最大嘗試請求, attemptNumber次
                .withStopStrategy(StopStrategies.stopAfterAttempt(attemptNumber))
                //等待策略乘陪,每次請求間隔1s
                .withWaitStrategy(WaitStrategies.fixedWait(sleepTime, TimeUnit.SECONDS))
                //嘗試請求時間限制,不能超過 taskTime
                .withAttemptTimeLimiter(new FixedAttemptTimeLimit(taskTime, TimeUnit.SECONDS, Executors.newCachedThreadPool()))
                //方法用于配置阻塞策略雕擂,指定在進行重試時的阻塞行為
                .withBlockStrategy(spinBlockStrategy)
                //重試過程的監(jiān)聽策略啡邑,打印了嘗試的次數(shù)
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        log.info("嘗試次數(shù) " + attempt.getAttemptNumber());
                    }
                })
                .build();
        try {
            return retryer.call(task);
        } catch (RetryException | ExecutionException e) {
            //throw inner exception
            String msg = "";
            log.error("retry internal error: {}", msg);
            throw new RuntimeException(msg);
        }
    }

guava-retrying3 結(jié)合testng使用,如果當(dāng)我們Assert來作為判斷任務(wù)的嘗試條件時井赌,有一個點需要注意惋耙,retry中的 call 方法最終拋出的對象為 throw new ExecutionError((Error)cause)网棍,這邊 new 出了一個 com.google.common.util.concurrent.ExecutionError 類的對象。而不是 java.util 類的。因此硅堆,我們需要重寫重試報錯類型


image.png

代碼中call的方法

retryer.call(task)

 private void wrapAndThrowRuntimeExecutionExceptionOrError(Throwable cause) {
        if (cause instanceof Error) {
            throw new ExecutionError((Error)cause);
        } else {
            throw new UncheckedExecutionException(cause);
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市记某,隨后出現(xiàn)的幾起案子痊夭,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件果漾,死亡現(xiàn)場離奇詭異球切,居然都是意外死亡,警方通過查閱死者的電腦和手機绒障,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門吨凑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人户辱,你說我怎么就攤上這事鸵钝。” “怎么了庐镐?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵蒋伦,是天一觀的道長。 經(jīng)常有香客問我焚鹊,道長痕届,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任末患,我火速辦了婚禮研叫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘璧针。我一直安慰自己嚷炉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布探橱。 她就那樣靜靜地躺著申屹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪隧膏。 梳的紋絲不亂的頭發(fā)上哗讥,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音胞枕,去河邊找鬼杆煞。 笑死,一個胖子當(dāng)著我的面吹牛腐泻,可吹牛的內(nèi)容都是我干的决乎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼派桩,長吁一口氣:“原來是場噩夢啊……” “哼构诚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起铆惑,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤范嘱,失蹤者是張志新(化名)和其女友劉穎送膳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體彤侍,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡肠缨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盏阶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晒奕。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖名斟,靈堂內(nèi)的尸體忽然破棺而出脑慧,到底是詐尸還是另有隱情,我是刑警寧澤砰盐,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布闷袒,位于F島的核電站,受9級特大地震影響岩梳,放射性物質(zhì)發(fā)生泄漏囊骤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一冀值、第九天 我趴在偏房一處隱蔽的房頂上張望也物。 院中可真熱鬧,春花似錦列疗、人聲如沸滑蚯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽告材。三九已至,卻和暖如春古劲,著一層夾襖步出監(jiān)牢的瞬間斥赋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工绢慢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留灿渴,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓胰舆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蹬挤。 傳聞我的和親對象是個殘疾皇子缚窿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容