您的位置:首页 > 编程语言 > Java开发

spring-retry注解方式使用(断路器,重试)

2017-10-03 00:26 471 查看

一. 在pom.xml中加入依赖

<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>


二.@CircuitBreaker

描述:标注需要短路的方法

参数

maxAttempts: 短路执行次数

openTimeout: 短路执行时间

resetTimeout:短路重试时间,当连续两次触发短路时,短路时间=openTimeout+resetTimeout

label:短路器的名字,系统唯一

include:需要短路的异常

exclude:不需要短路的异常

三.@Retryable

描述:标注需要重试的方法

参数

label: 重试的名字,系统唯一

maxAttempts:异常时重试次数

include:需要重试的异常

exclude:不需要重试的异常

四.@Recover

描述: 用来标注二触发短路,三触触发重试失败时,触发的恢复方法。该注解的反法必须和二,三注解的反法在同一个类中,详细见类
RecoverAnnotationRecoveryHandler


参数:

标注方法入参: 可以有或者没有,如果有,则是异常时的异常

标注方法返回值: 可替代二或者三失败时返回值

五.示例程序

package com.reger.test.retry;

import java.util.concurrent.TimeUnit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.CircuitBreaker;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;

@SpringBootApplication
@EnableRetry(proxyTargetClass=true)
public class SpringBootStarterRetryDemoApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootStarterRetryDemoApplication.class, args);
}

@EventListener
public void contextEvent(ContextRefreshedEvent contextEvent) throws InterruptedException {
SpringBootStarterRetryDemoApplication demoApplication=contextEvent.getApplicationContext().getBean(SpringBootStarterRetryDemoApplication.class);
System.err.println("尝试进入断路器方法,并触发异常");

demoApplication.circuitBreaker(1);
demoApplication.circuitBreaker(1);
demoApplication.circuitBreaker(1);

System.err.println("尝试进入断路器方法,在openTimeout时间内,触发异常超过3次,断路器打开,断路器方法不允许执行,直接执行恢复方法");
demoApplication.circuitBreaker(2);
TimeUnit.SECONDS.sleep(2);
System.err.println("超过断路器半开时间resetTimeout,断路器半开,断路器方法运行允许3个访问进入");
demoApplication.circuitBreaker(3);
demoApplication.circuitBreaker(3);
demoApplication.circuitBreaker(3);
System.err.println("尝试进入断路器方法,在openTimeout时间内,触发异常超过3次,断路器打开,断路器方法不允许执行,直接执行恢复方法");
demoApplication.circuitBreaker(4);
TimeUnit.SECONDS.sleep(3);
System.err.println("超过断路器再次超过半开时间openTimeout+resetTimeout,断路器半开,断路器方法运行允许三个访问进入");
demoApplication.circuitBreaker(5);
demoApplication.circuitBreaker(5);
demoApplication.circuitBreaker(5);
System.err.println("尝试进入断路器方法,在openTimeout时间内,触发异常超过3次,断路器打开,断路器方法不允许执行,直接执行恢复方法");
demoApplication.circuitBreaker(6);
TimeUnit.SECONDS.sleep(3);
System.err.println("超过断路器再次超过半开时间openTimeout+resetTimeout,断路器半开,断路器方法运行允许三个访问进入");
demoApplication.circuitBreaker(7);
demoApplication.circuitBreaker(7);
demoApplication.circuitBreaker(7);
System.err.println("尝试进入断路器方法,在openTimeout时间内,触发异常超过3次,断路器打开,断路器方法不允许执行,直接执行恢复方法");
demoApplication.circuitBreaker(8);
TimeUnit.SECONDS.sleep(3);
System.err.println("超过断路器再次超过半开时间openTimeout+resetTimeout,断路器半开,断路器方法运行允许三个访问进入,并且断路方法不再抛出异常,断路器关闭,方法可持续调用");
demoApplication.circuitBreaker(9);
demoApplication.circuitBreaker(9);
demoApplication.circuitBreaker(9);
demoApplication.circuitBreaker(9);
demoApplication.circuitBreaker(9);
demoApplication.circuitBreaker(9);

System.err.println();
System.err.println();
System.err.println("开始重试");
demoApplication.retryable(10);
System.err.println("未抛出异常,");
demoApplication.retryable(11);
}

@CircuitBreaker(maxAttempts=3,openTimeout=1000,resetTimeout=2000,label="test-CircuitBreaker",include=RuntimeException.class,exclude=Exception.class)
public void circuitBreaker(int num) throws InterruptedException {
System.err.print(" 进入断路器方法num="+num);
if(num>8)return;
Integer n=null;
System.err.println(1/n);
}

@Retryable(label="test-Retryable" , maxAttempts=3,backoff=@Backoff(delay=1),include=RuntimeException.class,exclude=Exception.class)
public void retryable(int num)  throws InterruptedException {
System.err.println(" 进入重试方法num="+num);
if(num>10)return;
Integer n=null;
System.err.println(1/n);
}

@Recover
public void recover(NullPointerException exception) {
System.err.println(" NullPointerException ....");
}

@Recover
public void recover(RuntimeException exception) {
System.err.println(" RuntimeException ....");
}

@Recover
public void recover(Exception exception) {
System.err.println(" exception ....");
}

@Recover
public void recover(Throwable throwable) {
System.err.println(" throwable ....");
}
@Recover
public void recover() {
System.err.println(" recover ....");
}
}


六.示例输出的日志

尝试进入断路器方法,并触发异常
进入断路器方法num=1 NullPointerException ....
进入断路器方法num=1 NullPointerException ....
进入断路器方法num=1 NullPointerException ....
尝试进入断路器方法,在openTimeout时间内,触发异常超过3次,断路器打开,断路器方法不允许执行,直接执行恢复方法
NullPointerException ....
超过断路器半开时间resetTimeout,断路器半开,断路器方法运行允许3个访问进入
进入断路器方法num=3 NullPointerException ....
进入断路器方法num=3 NullPointerException ....
进入断路器方法num=3 NullPointerException ....
尝试进入断路器方法,在openTimeout时间内,触发异常超过3次,断路器打开,断路器方法不允许执行,直接执行恢复方法
NullPointerException ....
超过断路器再次超过半开时间openTimeout+resetTimeout,断路器半开,断路器方法运行允许三个访问进入
进入断路器方法num=5 NullPointerException ....
进入断路器方法num=5 NullPointerException ....
进入断路器方法num=5 NullPointerException ....
尝试进入断路器方法,在openTimeout时间内,触发异常超过3次,断路器打开,断路器方法不允许执行,直接执行恢复方法
NullPointerException ....
超过断路器再次超过半开时间openTimeout+resetTimeout,断路器半开,断路器方法运行允许三个访问进入
进入断路器方法num=7 NullPointerException ....
进入断路器方法num=7 NullPointerException ....
进入断路器方法num=7 NullPointerException ....
尝试进入断路器方法,在openTimeout时间内,触发异常超过3次,断路器打开,断路器方法不允许执行,直接执行恢复方法
NullPointerException ....
超过断路器再次超过半开时间openTimeout+resetTimeout,断路器半开,断路器方法运行允许三个访问进入,并且断路方法不再抛出异常,断路器关闭,方法可持续调用
进入断路器方法num=9 进入断路器方法num=9 进入断路器方法num=9 进入断路器方法num=9 进入断路器方法num=9 进入断路器方法num=9

开始重试
进入重试方法num=10
进入重试方法num=10
进入重试方法num=10
NullPointerException ....
未抛出异常,
进入重试方法num=11
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息