SpringBoot技术实践-SpringRetry重试框架,java程序员面试笔试宝典

SpringBoot技术实践-SpringRetry重试框架,java程序员面试笔试宝典,第1张

SpringBoot技术实践-SpringRetry重试框架,java程序员面试笔试宝典

import com.codecoord.util.PrintUtil;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.retry.RetryCallback;

import org.springframework.retry.RetryContext;

import org.springframework.retry.RetryListener;

import org.springframework.retry.backoff.ExponentialBackOffPolicy;

import org.springframework.retry.policy.SimpleRetryPolicy;

import org.springframework.retry.support.RetryTemplate;

@Configuration

public class RetryTemplateConfig {

@Bean

public RetryTemplate retryTemplate() {

RetryTemplate retryTemplate = new RetryTemplate();

/// 回退固定时间(秒)

// 指数回退(秒),第一次回退1s,第二次回退2s

ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();

exponentialBackOffPolicy.setInitialInterval(1000L);

exponentialBackOffPolicy.setMultiplier(2);

retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);

// 重试策略

SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();

retryPolicy.setMaxAttempts(5);

retryTemplate.setRetryPolicy(retryPolicy);

// 设置监听器,open和close分别在启动和结束时执行一次

RetryListener[] listeners = {

new RetryListener() {

@Override

public boolean open(RetryContext context, RetryCallback callback) {

PrintUtil.print(“open”);

return true;

}

@Override

public void close(RetryContext context, RetryCallback callback,

Throwable throwable) {

PrintUtil.print(“close”);

}

@Override

public void onError(RetryContext context, RetryCallback callback,

Throwable throwable) {

PrintUtil.print(“onError”);

}

}

};

retryTemplate.setListeners(listeners);

return retryTemplate;

}

}

  1. 在controller中注入RetryTemplate使用,也可以是在service中

@RestController

public class SpringRetryController {

@Resource

private RetryTemplate retryTemplate;

private static int count = 0;

@RequestMapping("/retry")

public Object retry() {

try {

count = 0;

retryTemplate.execute((RetryCallback) context -> {

// 业务代码

// …

// 模拟抛出异常

++count;

throw new RuntimeException(“抛出异常”);

});

} catch (RuntimeException e) {

System.out.println(“Exception”);

}

return "retry = " + count;

}

}

  1. 访问retry接口,然后观察日志输出

18:27:20.648 - http-nio-8888-exec-1 - open

18:27:20.649 - http-nio-8888-exec-1 - retryTemplate.execute执行

18:27:20.649 - http-nio-8888-exec-1 - onError

18:27:21.658 - http-nio-8888-exec-1 - retryTemplate.execute执行

18:27:21.658 - http-nio-8888-exec-1 - onError

18:27:23.670 - http-nio-8888-exec-1 - retryTemplate.execute执行

18:27:23.670 - http-nio-8888-exec-1 - onError

18:27:27.679 - http-nio-8888-exec-1 - retryTemplate.execute执行

18:27:27.679 - http-nio-8888-exec-1 - onError

18:27:35.681 - http-nio-8888-exec-1 - retryTemplate.execute执行

18:27:35.681 - http-nio-8888-exec-1 - onError

18:27:35.681 - http-nio-8888-exec-1 - close

三、EnableRetry

================================================================================

  1. @EnableRetry开启重试,在类上指定的时候方法默认执行,重试三次

  2. 定义service,开启@EnableRetry注解和指定@Retryable,重试可以参考后面一节

import org.springframework.retry.annotation.Retryable;

public interface RetryService {

@Retryable

void retryServiceCall();

}

import org.springframework.retry.annotation.EnableRetry;

import org.springframework.stereotype.Service;

@EnableRetry

@Service

public class RetryServiceImpl implements RetryService {

@Override

public void retryServiceCall() {

PrintUtil.print(“方法调用…”);

throw new RuntimeException(“手工异常”);

}

}

  1. controller中注入service

@RequestMapping("/retryAnnotation")

public Object retryAnnotation() {

retryService.retryServiceCall();

return “retryAnnotation”;

}

  1. 将会默认重试

18:46:48.721 - http-nio-8888-exec-1 - 方法调用…

18:46:49.724 - http-nio-8888-exec-1 - 方法调用…

18:46:50.730 - http-nio-8888-exec-1 - 方法调用…

java.lang.RuntimeException: 手工异常

四、Retryable

==============================================================================

  1. 用于需要重试的方法上的注解

  2. 有以下几个属性

  • Retryable注解参数

  • value:指定发生的异常进行重试

  • include:和value一样,默认空,当exclude也为空时,所有异常都重试

  • exclude:指定异常不重试,默认空,当include也为空时,所有异常都重试

  • maxAttemps:重试次数,默认3

  • backoff:重试补偿机制,默认没有

  • @Backoff 注解 重试补偿策略

  • 不设置参数时,默认使用FixedBackOffPolicy(指定等待时间),重试等待1000ms

  • 设置delay,使用FixedBackOffPolicy(指定等待设置delay和maxDealy时,重试等待在这两个值之间均态分布)

  • 设置delay、maxDealy、multiplier,使用 ExponentialBackOffPolicy(指数级重试间隔的实现),multiplier即指定延迟倍数,比如delay=5000L,multiplier=2,则第一次重试为5秒,第二次为10秒,第三次为20秒

@Target({ ElementType.METHOD, ElementType.TYPE })

@Retention(RetentionPolicy.RUNTIME)

@documented

public @interface Retryable {

String interceptor() default “”;

Class[] value() default {};

Class[] include() default {};

Class[] exclude() default {};

String label() default “”;

boolean stateful() default false;

int maxAttempts() default 3;

String maxAttemptsexpression() default “”;

Backoff backoff() default @Backoff();

String exceptionexpression() default “”;

String[] listeners() default {};

}

  1. 在需要重试的方法上配置对应的重试次数、重试异常的异常类型、设置回退延迟时间、重试策略、方法监听名称

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@documented

public @interface Backoff {

long value() default 1000;

long delay() default 0;

long maxDelay() default 0;

double multiplier() default 0;

String delayexpression() default “”;

String maxDelayexpression() default “”;

String multiplierexpression() default “”;

boolean random() default false;

}

@Component

public class PlatformClassService {

@Retryable(

// 重试异常的异常类型

value = {Exception.class},

// 最大重试次数

maxAttempts = 5,

// 设置回退延迟时间

backoff = @Backoff(delay = 500),

// 配置回调方法名称

listeners = “retryListener”

)

public void call() {

System.out.println(“call…”);

throw new RuntimeException(“手工异常”);

}

}

// 初始延迟2秒,然后之后验收1.5倍延迟重试,总重试次数4

@Retryable(value = {Exception.class}, maxAttempts = 4, backoff = @Backoff(delay = 2000L, multiplier = 1.5))

  1. 监听方法,在配置类中进行配置

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5672603.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存