国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 詳解重試框架Spring retry實踐

詳解重試框架Spring retry實踐

2021-04-27 11:28rhwayfunn Java教程

spring retry是從spring batch獨立出來的一個能功能,主要實現(xiàn)了重試和熔斷。這篇文章主要介紹了詳解重試框架Spring retry實踐,具有一定的參考價值,感興趣的小伙伴們可以參考一下

spring retry是從spring batch獨立出來的一個能功能,主要實現(xiàn)了重試和熔斷。對于重試是有場景限制的,不是什么場景都適合重試,比如參數(shù)校驗不合法、寫操作等(要考慮寫是否冪等)都不適合重試。遠程調(diào)用超時、網(wǎng)絡(luò)突然中斷可以重試。在微服務(wù)治理框架中,通常都有自己的重試與超時配置,比如dubbo可以設(shè)置retries=1,timeout=500調(diào)用失敗只重試1次,超過500ms調(diào)用仍未返回則調(diào)用失敗。在spring retry中可以指定需要重試的異常類型,并設(shè)置每次重試的間隔以及如果重試失敗是繼續(xù)重試還是熔斷(停止重試)。

設(shè)計與實現(xiàn)

retryoperations定義重試的api,retrytemplate是api的模板模式實現(xiàn),實現(xiàn)了重試和熔斷。提供的api如下:

?
1
2
3
4
public interface retryoperations {
  <t, e extends throwable>t execute(retrycallback<t, e>retrycallback) throws e;
  }
  // 其他api已省略

retrycallback定義了需要執(zhí)行重試的操作,定義好操作后,就是如何重試的問題了。retrytemplate通過制定不同的重試策略來執(zhí)行如何重試的邏輯。默認的重試策略是simpleretryplicy,也就是會重試3次。重試第1次如果成功后面就不會繼續(xù)重試了。那么如果3尺都重試失敗了呢?流程結(jié)束或者返回兜底結(jié)果。要返回兜底結(jié)果需要配置recoveycallback,從名字可以看出這是一個兜底回調(diào)接口,也就是重試失敗后執(zhí)行的邏輯。除了simpleretrypolicy還有其他重試策略,先來看下retrypolicy接口:

?
1
2
3
4
5
6
public interface retrypolicy extends serializable {
  boolean canretry(retrycontext context);
  retrycontext open(retrycontext parent);
  void close(retrycontext context);
  void registerthrowable(retrycontext context, throwable throwable);
}

canretry在每次重試的時候調(diào)用,是否可以繼續(xù)重試的判斷條件
open重試開始前調(diào)用,會創(chuàng)建一個重試上下文到retrycontext,保存重試的堆棧等信息
registerthrowable每次重試異常時調(diào)用(有異常會繼續(xù)重試)

simpleretrypolicy為例,當重試次數(shù)達到3(默認3次)停止重試,重試次數(shù)保存在重試上下文中。

提供如下重試策略實現(xiàn):

詳解重試框架Spring retry實踐

  1. neverretrypolicy:只允許調(diào)用retrycallback一次,不允許重試
  2. alwaysretrypolicy:允許無限重試,直到成功,此方式邏輯不當會導(dǎo)致死循環(huán)
  3. simpleretrypolicy:固定次數(shù)重試策略,默認重試最大次數(shù)為3次,retrytemplate默認使用的策略
  4. timeoutretrypolicy:超時時間重試策略,默認超時時間為1秒,在指定的超時時間內(nèi)允許重試
  5. exceptionclassifierretrypolicy:設(shè)置不同異常的重試策略,類似組合重試策略,區(qū)別在于這里只區(qū)分不同異常的重試
  6. circuitbreakerretrypolicy:有熔斷功能的重試策略,需設(shè)置3個參數(shù)opentimeout、resettimeout和delegate
  7. compositeretrypolicy:組合重試策略,有兩種組合方式,樂觀組合重試策略是指只要有一個策略允許重試即可以,悲觀組合重試策略是指只要有一個策略不允許重試即可以,但不管哪種組合方式,組合中的每一個策略都會執(zhí)行

重試回退策略,指的是每次重試是立即重試還是等待一段時間后重試。默認情況下是立即重試,如果需要配置等待一段時間后重試則需要指定回退策略backoffretrypolicy。backoffretrypolicy有如下實現(xiàn):

詳解重試框架Spring retry實踐

  1. nobackoffpolicy:無退避算法策略,每次重試時立即重試
  2. fixedbackoffpolicy:固定時間的退避策略,需設(shè)置參數(shù)sleeper和backoffperiod,sleeper指定等待策略,默認是thread.sleep,即線程休眠,backoffperiod指定休眠時間,默認1秒
  3. uniformrandombackoffpolicy:隨機時間退避策略,需設(shè)置sleeper、minbackoffperiod和maxbackoffperiod,該策略在[minbackoffperiod,maxbackoffperiod之間取一個隨機休眠時間,minbackoffperiod默認500毫秒,maxbackoffperiod默認1500毫秒
  4. exponentialbackoffpolicy:指數(shù)退避策略,需設(shè)置參數(shù)sleeper、initialinterval、maxinterval和multiplier,initialinterval指定初始休眠時間,默認100毫秒,maxinterval指定最大休眠時間,默認30秒,multiplier指定乘數(shù),即下一次休眠時間為當前休眠時間*multiplier
  5. exponentialrandombackoffpolicy:隨機指數(shù)退避策略,引入隨機乘數(shù)可以實現(xiàn)隨機乘數(shù)回退

有狀態(tài)重試 or 無狀態(tài)重試

所謂無狀態(tài)重試是指重試在一個線程上下文中完成的重試,反之不在一個線程上下文完成重試的就是有狀態(tài)重試。之前的simpleretrypolicy就屬于無狀態(tài)重試,因為重試是在一個循環(huán)中完成的。那么什么會后會出現(xiàn)或者說需要有狀態(tài)重試呢?通常有兩種情況:事務(wù)回滾和熔斷。

數(shù)據(jù)庫操作異常dataaccessexception,不能執(zhí)行重試,而如果拋出其他異常可以重試。

熔斷的意思不在當前循環(huán)中處理重試,而是全局重試模式(不是線程上下文)。熔斷會跳出循環(huán),那么必然會丟失線程上下文的堆棧信息。那么肯定需要一種“全局模式”保存這種信息,目前的實現(xiàn)放在一個cache(map實現(xiàn)的)中,下次從緩存中獲取就能繼續(xù)重試了。

quick start

在需要執(zhí)行重試的類上使用@enableretry,如果設(shè)置了proxytargetclass=true這使用cglib動態(tài)代理:

?
1
2
3
4
5
6
@configuration
@enableretry(proxytargetclass = true)
@component
public class retryexamples {
 
}

基于最大重試次數(shù)策略的重試,如果重試了3次仍然拋出異常則停止重試,執(zhí)行兜底回調(diào),所以最后的輸出結(jié)果是integer.max_value

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
private void retryexample3() throws exception {
    retrytemplate retrytemplate = new retrytemplate();
 
    simpleretrypolicy simpleretrypolicy = new simpleretrypolicy();
    simpleretrypolicy.setmaxattempts(3);
 
    retrytemplate.setretrypolicy(simpleretrypolicy);
 
    integer result = retrytemplate.execute(new retrycallback<integer, exception>() {
      int i = 0;
 
       // 重試操作
      @override
      public integer dowithretry(retrycontext retrycontext) throws exception {
        log.info("retry count: {}", retrycontext.getretrycount());
        return len(i++);
      }
    }, new recoverycallback<integer>() { //兜底回調(diào)
      @override
      public integer recover(retrycontext retrycontext) throws exception {
        log.info("after retry: {}, recovery method called!", retrycontext.getretrycount());
        return integer.max_value;
      }
    });
    log.info("final result: {}", result);
  }
 
  private int len(int i) throws exception {
    if (i < 10) throw new exception(i + " le 10");
    return i;
  }

下面介紹如何使用熔斷重試策略模式(circuitbreakerretrypolicy),需要設(shè)置如下三個參數(shù):

  1. delegate:傳入retrypolicy(每個retrypolicy實現(xiàn)都有自己的重試策略實現(xiàn)),是真正判斷是否重試的策略,當重試失敗時,則執(zhí)行熔斷策略
  2. opentimeout:openwindow,配置熔斷器電路打開的超時時間,當超過opentimeout之后熔斷器電路變成半打開狀態(tài)(只要有一次重試成功,則閉合電路)
  3. resettimeout:timeout,配置重置熔斷器重新閉合的超時時間

斷路器開閉實現(xiàn)判斷:

詳解重試框架Spring retry實踐

  1. 當重試失敗,且在熔斷器打開時間窗口[0,openwindow) 內(nèi),立即熔斷
  2. 當重試失敗,且超過timeout,熔斷器電路重新閉合
  3. 在熔斷器半打開狀態(tài)[openwindow, timeout] 時,只要重試成功則重置上下文,斷路器閉合

測試代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
retrytemplate template = new retrytemplate();
    circuitbreakerretrypolicy retrypolicy =
        new circuitbreakerretrypolicy(new simpleretrypolicy(3));
    retrypolicy.setopentimeout(5000);
    retrypolicy.setresettimeout(20000);
    template.setretrypolicy(retrypolicy);
 
    for (int i = 0; i < 10; i++) {
      //thread.sleep(100);
      try {
        object key = "circuit";
        boolean isforcerefresh = false;
        retrystate state = new defaultretrystate(key, isforcerefresh);
        string result = template.execute(new retrycallback<string, runtimeexception>() {
          @override
          public string dowithretry(retrycontext context) throws runtimeexception {
            log.info("retry count: {}", context.getretrycount());
            throw new runtimeexception("timeout");
          }
        }, new recoverycallback<string>() {
          @override
          public string recover(retrycontext context) throws exception {
            return "default";
          }
        }, state);
        log.info("result: {}", result);
      } catch (exception e) {
        system.out.println(e);
      }
    }

這里由于設(shè)置了isforcerefresh = false,則key = "circuit"的值(也就是retrycontext)會從緩存中獲取,所以當重試失敗且滿足this.time < this.openwindow發(fā)生熔斷的時候,后面仍然可以繼續(xù)已全局模式實現(xiàn)重試(拿到的retrycontext是同一個)。

注解開發(fā)

如果每次有重試需求的時候都寫一個retrytemplate太臃腫了,使用注解可以大大簡化開發(fā),減少重復(fù)代碼。下面是一個使用注解實現(xiàn)的最大重試策略的重試:

?
1
2
3
4
5
6
7
8
9
10
@retryable(value = sqldataexception.class, backoff = @backoff(value = 0l))
  public string service3() throws sqldataexception {
    log.info("service3 open");
    throw new sqldataexception();
  }
 
  @recover
  public string recover(sqldataexception ne) {
    return "sqldataexception recover";
  }

注解包括:

@enableretry

@retryable

@recover

@backoff

@circuitbreaker

@enableretry:能否重試,proxytargetclass屬性為true時(默認false),使用cglib代理

@retryable:注解需要被重試的方法

  1. include 指定處理的異常類。默認為空
  2. exclude指定不需要處理的異常。默認為空
  3. vaue指定要重試的異常。默認為空
  4. maxattempts 最大重試次數(shù)。默認3次
  5. backoff 重試等待策略。默認使用@backoff注解

@backoff:重試回退策略(立即重試還是等待一會再重試)

  1. 不設(shè)置參數(shù)時,默認使用fixedbackoffpolicy,重試等待1000ms
  2. 只設(shè)置delay()屬性時,使用fixedbackoffpolicy,重試等待指定的毫秒數(shù)
  3. 當設(shè)置delay()和maxdealy()屬性時,重試等待在這兩個值之間均態(tài)分布
  4. 使用delay(),maxdealy()和multiplier()屬性時,使用exponentialbackoffpolicy
  5. 當設(shè)置multiplier()屬性不等于0時,同時也設(shè)置了random()屬性時,使用exponentialrandombackoffpolicy

@recover: 用于方法。用于@retryable失敗時的“兜底”處理方法。 @recover注釋的方法必須要與@retryable注解的方法“簽名”保持一致,第一入?yún)橐卦嚨漠惓?,其他參?shù)與@retryable保持一致,返回值也要一樣,否則無法執(zhí)行!

@circuitbreaker:用于方法,實現(xiàn)熔斷模式。

  1. include 指定處理的異常類。默認為空
  2. exclude指定不需要處理的異常。默認為空
  3. vaue指定要重試的異常。默認為空
  4. maxattempts 最大重試次數(shù)。默認3次
  5. opentimeout 配置熔斷器打開的超時時間,默認5s,當超過opentimeout之后熔斷器電路變成半打開狀態(tài)(只要有一次重試成功,則閉合電路)
  6. resettimeout 配置熔斷器重新閉合的超時時間,默認20s,超過這個時間斷路器關(guān)閉

更多的例子歡迎到我的github(https://github.com/happyxiaofan/springboot-learning-example) star。謝謝

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/u011116672/article/details/77823867

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 天天射天天干 | 精品久久99 | 亚洲 自拍 另类 欧美 丝袜 | 国产亚洲精品久久久久动 | 色综合99 | 亚洲男人在线天堂 | 婷婷精品久久久久久久久久不卡 | 黄网页在线观看 | 精品久久久久久久久久久下田 | 日韩一区电影 | 亚州国产| 色偷偷888欧美精品久久久 | 午夜久久久 | 老黄网站在线观看 | 日本久久久久久 | 日本精品视频在线观看 | 九色视频网站 | 国产精品毛片一区二区 | 亚洲精品专区 | 久久久久久久9 | av有声小说一区二区三区 | 成人综合视频在线 | 欧美成人一区二区三区片免费 | 国产日韩久久 | 久久午夜影院 | 亚洲精品成人av | 91精品国产高清久久久久久久久 | 精品在线一区二区 | av在线一区二区 | 久久亚洲欧美日韩精品专区 | 欧美成人伊人 | 一区二区三区免费在线观看 | 欧美在线资源 | 午夜精品视频 | 精品国产乱码久久久久久久软件 | 精品欧美一区二区三区久久久 | 国产乱xxxxx97国语对白 | 91精品国产综合久久福利软件 | 在线免费av观看 | 羞羞视频免费观看 | 成人午夜精品久久久久久久3d |