成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Spring Cloud Gateway重試機制原理解析

瀏覽:107日期:2023-08-21 15:37:58

重試,我相信大家并不陌生。在我們調用Http接口的時候,總會因為某種原因調用失敗,這個時候我們可以通過重試的方式,來重新請求接口。

生活中這樣的事例很多,比如打電話,對方正在通話中啊,信號不好啊等等原因,你總會打不通,當你第一次沒打通之后,你會打第二次,第三次…第四次就通了。

重試也要注意應用場景,讀數據的接口比較適合重試的場景,寫數據的接口就需要注意接口的冪等性了。還有就是重試次數如果太多的話會導致請求量加倍,給后端造成更大的壓力,設置合理的重試機制才是最關鍵的。今天我們來簡單的了解下Spring Cloud Gateway中的重試機制和使用。

使用講解

RetryGatewayFilter是Spring Cloud Gateway對請求重試提供的一個GatewayFilter Factory。

配置方式:

spring: cloud: gateway: routes: - id: fsh-house uri: lb://fsh-house predicates: - Path=/house/** filters: - name: Retry args: retries: 3 series: - SERVER_ERROR statuses: - OK methods: - GET - POST exceptions: - java.io.IOException

配置講解

配置類源碼:org.springframework.cloud.gateway.filter.factory.RetryGatewayFilterFactory.RetryConfig:

public static class RetryConfig { private int retries = 3; private List<Series> series = toList(Series.SERVER_ERROR); private List<HttpStatus> statuses = new ArrayList<>(); private List<HttpMethod> methods = toList(HttpMethod.GET); private List<Class<? extends Throwable>> exceptions = toList(IOException.class); // .....}

retries:重試次數,默認值是3次

series:狀態碼配置(分段),符合的某段狀態碼才會進行重試邏輯,默認值是SERVER_ERROR,值是5,也就是5XX(5開頭的狀態碼),共有5個值:

public enum Series { INFORMATIONAL(1), SUCCESSFUL(2), REDIRECTION(3), CLIENT_ERROR(4), SERVER_ERROR(5);}

statuses:狀態碼配置,和series不同的是這邊是具體狀態碼的配置,取值請參考:org.springframework.http.HttpStatus

methods:指定哪些方法的請求需要進行重試邏輯,默認值是GET方法,取值如下:

public enum HttpMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;}

exceptions:指定哪些異常需要進行重試邏輯,默認值是java.io.IOException

代碼測試

就寫個接口,在接口中記錄請求次數,然后拋出一個異常模擬500,通過網關訪問這個接口,如果你配置了重試次數是3,那么接口中會輸出4次結果才是對的,證明重試生效了。

AtomicInteger ac = new AtomicInteger();@GetMapping('/data')public HouseInfo getData(@RequestParam('name') String name) { if (StringUtils.isBlank(name)) { throw new RuntimeException('error'); } System.err.println(ac.addAndGet(1)); return new HouseInfo(1L, '上海', '虹口', 'XX小區');}

源碼欣賞

@Overridepublic GatewayFilter apply(RetryConfig retryConfig) { // 驗證重試配置格式是否正確 retryConfig.validate(); Repeat<ServerWebExchange> statusCodeRepeat = null; if (!retryConfig.getStatuses().isEmpty() || !retryConfig.getSeries().isEmpty()) { Predicate<RepeatContext<ServerWebExchange>> repeatPredicate = context -> { ServerWebExchange exchange = context.applicationContext(); // 判斷重試次數是否已經達到了配置的最大值 if (exceedsMaxIterations(exchange, retryConfig)) {return false; } // 獲取響應的狀態碼 HttpStatus statusCode = exchange.getResponse().getStatusCode(); // 獲取請求方法類型 HttpMethod httpMethod = exchange.getRequest().getMethod(); // 判斷響應狀態碼是否在配置中存在 boolean retryableStatusCode = retryConfig.getStatuses().contains(statusCode); if (!retryableStatusCode && statusCode != null) { // null status code might mean a network exception?// try the seriesretryableStatusCode = retryConfig.getSeries().stream() .anyMatch(series -> statusCode.series().equals(series)); } // 判斷方法是否包含在配置中 boolean retryableMethod = retryConfig.getMethods().contains(httpMethod); // 決定是否要進行重試 return retryableMethod && retryableStatusCode; }; statusCodeRepeat = Repeat.onlyIf(repeatPredicate).doOnRepeat(context -> reset(context.applicationContext())); } //TODO: support timeout, backoff, jitter, etc... in Builder Retry<ServerWebExchange> exceptionRetry = null; if (!retryConfig.getExceptions().isEmpty()) { Predicate<RetryContext<ServerWebExchange>> retryContextPredicate = context -> { if (exceedsMaxIterations(context.applicationContext(), retryConfig)) {return false; } // 異常判斷 for (Class<? extends Throwable> clazz : retryConfig.getExceptions()) { if (clazz.isInstance(context.exception())) { return true;} } return false; }; // 使用reactor extra的retry組件 exceptionRetry = Retry.onlyIf(retryContextPredicate).doOnRetry(context -> reset(context.applicationContext())).retryMax(retryConfig.getRetries()); } return apply(statusCodeRepeat, exceptionRetry);}public boolean exceedsMaxIterations(ServerWebExchange exchange, RetryConfig retryConfig) { Integer iteration = exchange.getAttribute(RETRY_ITERATION_KEY); //TODO: deal with null iteration return iteration != null && iteration >= retryConfig.getRetries();}public void reset(ServerWebExchange exchange) { //TODO: what else to do to reset SWE? exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_ALREADY_ROUTED_ATTR);}public GatewayFilter apply(Repeat<ServerWebExchange> repeat, Retry<ServerWebExchange> retry) { return (exchange, chain) -> { if (log.isTraceEnabled()) { log.trace('Entering retry-filter'); } // chain.filter returns a Mono<Void> Publisher<Void> publisher = chain.filter(exchange)//.log('retry-filter', Level.INFO).doOnSuccessOrError((aVoid, throwable) -> { // 獲取已經重試的次數,默認值為-1 int iteration = exchange.getAttributeOrDefault(RETRY_ITERATION_KEY, -1); // 增加重試次數 exchange.getAttributes().put(RETRY_ITERATION_KEY, iteration + 1);}); if (retry != null) { // retryWhen returns a Mono<Void> // retry needs to go before repeat publisher = ((Mono<Void>)publisher).retryWhen(retry.withApplicationContext(exchange)); } if (repeat != null) { // repeatWhen returns a Flux<Void> // so this needs to be last and the variable a Publisher<Void> publisher = ((Mono<Void>)publisher).repeatWhen(repeat.withApplicationContext(exchange)); } return Mono.fromDirect(publisher); };}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
成人综合在线视频| 亚洲欧美国产不卡| 国产日韩一区二区| 国产精品女人毛片| 欧美不卡在线| 精品va天堂亚洲国产| 国产成人av电影在线| 91精品一区二区三区在线观看| 日韩高清欧美激情| 欧美资源在线| 五月婷婷另类国产| 久久久福利视频| 亚洲与欧洲av电影| 国产精品av一区二区| 欧美国产日本韩| 色综合一区二区| 国产欧美日韩精品在线| 欧美二区在线| 欧美韩日一区二区三区四区| 91免费看`日韩一区二区| 2欧美一区二区三区在线观看视频| 国产aⅴ综合色| 在线91免费看| 国产高清不卡二三区| 日韩欧美中文一区| 成人综合婷婷国产精品久久| 精品欧美一区二区三区精品久久| 成人深夜福利app| 337p粉嫩大胆噜噜噜噜噜91av| 成人av在线网| 国产午夜久久久久| 国产一区二区三区四区三区四| 欧美韩国日本一区| 亚洲国产美女| 亚洲v中文字幕| 欧美伊人久久大香线蕉综合69| 日韩**一区毛片| 欧美日韩一区二区三区四区 | 国产精品沙发午睡系列990531| 国内自拍一区| 亚洲丰满少妇videoshd| 久久久久.com| 国产精品综合二区| 日韩三级伦理片妻子的秘密按摩| 99久久综合色| 午夜国产一区| 亚洲精品国产成人久久av盗摄| 蜜桃久久精品乱码一区二区| 美国欧美日韩国产在线播放| 91精品国产综合久久小美女| 91亚洲男人天堂| 亚洲靠逼com| 在线日韩国产精品| 成人午夜视频网站| 国产精品亲子乱子伦xxxx裸| 国产精品普通话对白| 青椒成人免费视频| 日韩欧美另类在线| 国产精品二区在线观看| 亚洲成精国产精品女| 欧美二区在线观看| 欧美午夜国产| 日韩中文字幕亚洲一区二区va在线| 欧美精品久久久久久久多人混战| 91丝袜呻吟高潮美腿白嫩在线观看| 亚洲伦在线观看| 在线影视一区二区三区| 成人国产精品视频| 亚洲精品综合在线| 91久久香蕉国产日韩欧美9色| 国产成人av一区二区| 欧美激情一区二区三区全黄| 久久久99爱| www.亚洲色图.com| 亚洲国产成人高清精品| 欧美一级日韩一级| 影音欧美亚洲| 毛片av一区二区三区| 久久综合一区二区| 香蕉成人久久| 成人一区在线看| 亚洲伊人色欲综合网| 欧美久久一区二区| 国产精品九九| 久久精品二区亚洲w码| 国产午夜精品理论片a级大结局| 国产精品婷婷| 粉嫩一区二区三区性色av| 国产精品国产三级国产普通话蜜臀| 色婷婷一区二区三区四区| voyeur盗摄精品| 性做久久久久久| 2023国产精品视频| 久久久精品五月天| 欧美一区国产一区| 午夜久久久久久| 久久嫩草精品久久久精品一| 毛片一区二区| 99国产一区二区三精品乱码| 亚洲第一狼人社区| 久久嫩草精品久久久精品一| 裸体丰满少妇做受久久99精品| 不卡一区中文字幕| 视频一区中文字幕国产| 久久久久久电影| 欧美亚洲综合在线| 一区三区视频| 国产很黄免费观看久久| 亚洲一区二区视频在线观看| 日韩欧美色综合| 久久综合九色综合网站| 欧美精品一区二区视频| 九色综合国产一区二区三区| **欧美大码日韩| 日韩欧美一卡二卡| 久久久久一区二区| 欧美高清一区二区| 老司机免费视频一区二区 | 美女尤物国产一区| 亚洲人成在线播放网站岛国| 欧美一激情一区二区三区| 久久精品伊人| 亚洲国产激情| 亚洲欧美一级二级三级| 国产米奇在线777精品观看| 亚洲专区一二三| 日本一区二区免费在线| 欧美一区二区三区色| 久久精品卡一| 在线欧美不卡| www.av亚洲| 国模套图日韩精品一区二区 | 成人精品免费网站| 久久国产综合精品| 亚洲成人自拍网| 综合中文字幕亚洲| 久久精品欧美日韩| 777xxx欧美| 在线观看日韩国产| 久久动漫亚洲| 亚洲开发第一视频在线播放| 91亚洲精品一区二区乱码| 黄色日韩三级电影| 天天影视网天天综合色在线播放| 亚洲天堂久久久久久久| 久久精品夜色噜噜亚洲a∨| 欧美一卡二卡在线| 欧美日韩mp4| 久久男女视频| 国产一区二区三区久久| 欧美在线播放一区二区| 成人精品免费视频| 国产suv精品一区二区883| 国产最新精品免费| 看片网站欧美日韩| 三级久久三级久久久| 亚洲综合999| 一区二区在线观看视频在线观看| 国产精品视频yy9299一区| 久久久不卡影院| 欧美一区二区三区免费| 在线视频中文字幕一区二区| 免费一区视频| 午夜一级久久| 国产一区二区高清不卡| aa成人免费视频| 日韩午夜精品| 国产欧美日韩亚洲| 亚洲深爱激情| 99热免费精品在线观看| 亚洲高清电影| 亚洲高清毛片| 亚洲高清不卡| 一区二区三区国产盗摄| 亚洲欧洲日本国产| 亚洲片区在线| 国产区日韩欧美| 亚洲欧美日韩精品久久久| 亚洲一区二区在线看| 国产精品试看| 久久精品日产第一区二区| 久久成人亚洲| 另类av一区二区| 色悠悠久久综合| 色域天天综合网| 欧洲人成人精品| 欧美中文一区二区三区| 一本久道中文字幕精品亚洲嫩| 色噜噜狠狠一区二区三区果冻| 色噜噜久久综合| 欧美日韩三级在线| 日韩欧美一区中文| 精品国产污污免费网站入口| 国产亚洲一区二区三区在线观看| 国产丝袜美腿一区二区三区| 欧美激情一区二区在线| 亚洲免费高清视频在线| 亚洲不卡av一区二区三区| 欧美96一区二区免费视频| 久久精品99国产精品日本|