springboot(十四)使用spring retry

2022年10月5日09:16:49

在调用第三方接口或者使用mq时,会出现网络抖动,连接超时等网络异常,所以需要重试。

1、引入jar包

<dependency>
			<groupId>org.springframework.retry</groupId>
			<artifactId>spring-retry</artifactId>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
		</dependency>

2、模拟网络异常,创建一个异常

package com.demo.exception;

import lombok.Builder;
import lombok.Getter;

/**
 * Created by huguoju on 2017/4/13.
 */
@Builder
@Getter
public class RetryException extends RuntimeException {
    private String code;
    private String message;
}

3、在Application上添加@EnableRetry开启Retry服务

@EnableRetry
public class SpringbootApplication {

4、在service模拟访问异常,抛出异常

package com.demo.service.impl;

import com.demo.exception.RetryException;
import com.demo.service.RetryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

/**
 * Created by huguoju on 2017/4/13.
 */
@Service("retryService")
@Slf4j
public class RetryServiceImpl implements RetryService {
    int i=1;
    @Override
    @Retryable(value = {RuntimeException.class},maxAttempts = 4,backoff = @Backoff(delay = 1000l,multiplier = 1))
    public String retry() {
        log.info("测试retry");
        i++;//生产环境此处应该为调用第三方接口,判断接口返回code
        if(i==3){
            return i+"";
        }
        RetryException retryException=RetryException.builder().code("9999").message("连接超时").build();
        throw retryException;
    }

 
    @Recover
    public String recover(RetryException e){
        log.info(e.getMessage());
        return "6";
    }
}

说明:

@Retryable:标注此注解的方法在发生异常时会进行重试
参数说明:value:抛出指定异常才会重试
          include:和value一样,默认为空,当exclude也为空时,默认所以异常
          exclude:指定不处理的异常
          maxAttempts:最大重试次数,默认3次
          backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,multiplier(指定延迟倍数)
                   默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为2,则第一次重试为1秒,第二次为
                   2秒,第三次为4秒
@Recover:用于@Retryable重试失败后处理方法,此方法里的异常一定要是@Retryable方法里抛出的异常,否则不会调用
          这个方法


5、在其他service里调用上面的service抛出异常
@Override
    public Map testRetry() {
        Map map= Maps.newHashMap();
        String s=retryService.retry();
        if (s.equals("3")){
            log.info("成功啦啦啦啦啦啦啦啦");
        }else {
            log.info("失败了");
        }
        map.put("result",s);
        return map;
    }

6、定义测试controller
package com.demo.controller;

import com.demo.service.RetryService;
import com.demo.service.TestService;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * Created by huguoju on 2017/4/13.
 */
@RestController
@RequestMapping("retry")
@Api(value = "重试机制",tags = "重试机制")
public class RetryController {
    @Autowired
    public TestService testService;
    @RequestMapping(value = "testRetry",method = {RequestMethod.POST,RequestMethod.GET},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Map testRetry(){
        Map map=Maps.newHashMap();
        try {
            map= testService.testRetry();
            return map;
        }catch (Exception e){
            e.printStackTrace();
            return map;
        }
    }
}

访问controller,看日志输出

15:21:30 WARN  [qtp1129243682-21]  com.atomikos.icatch.imp.TransactionServiceImp - Attempt to create a transaction with a timeout that exceeds com.atomikos.icatch.max_timeout - truncating to: 300000
15:21:30 INFO  [qtp1129243682-21]  com.atomikos.icatch.imp.BaseTransactionManager - createCompositeTransaction ( 10000000 ): created new ROOT transaction with id 10.3.5.31.tm0000100002
15:21:30 INFO  [qtp1129243682-21]  com.demo.service.impl.RetryServiceImpl - 测试retry
15:21:31 INFO  [qtp1129243682-21]  com.demo.service.impl.RetryServiceImpl - 测试retry
15:21:31 INFO  [qtp1129243682-21]  com.demo.service.impl.TestServiceImpl - 成功啦啦啦啦啦啦啦啦
15:21:31 INFO  [qtp1129243682-21]  com.atomikos.icatch.imp.CompositeTransactionImp - commit() done (by application) of transaction 10.3.5.31.tm0000100002

要测试@Recover,即一直异常,只需要把RetryServiceImpl里的if(i==3)改为if(i==6),把调用service里if(s.equals("3"))改完if(s.equals("6)),然后重新访问,日志:

15:26:54 WARN  [qtp1870436181-20]  com.atomikos.icatch.imp.TransactionServiceImp - Attempt to create a transaction with a timeout that exceeds com.atomikos.icatch.max_timeout - truncating to: 300000
15:26:54 INFO  [qtp1870436181-20]  com.atomikos.icatch.imp.BaseTransactionManager - createCompositeTransaction ( 10000000 ): created new ROOT transaction with id 10.3.5.31.tm0000100003
15:26:54 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry
15:26:55 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry
15:26:56 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry
15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry
15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 连接超时
15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.TestServiceImpl - 成功啦啦啦啦啦啦啦啦
15:26:57 INFO  [qtp1870436181-20]  com.atomikos.icatch.imp.CompositeTransactionImp - commit() done (by application) of transaction 10.3.5.31.tm0000100003
  • 作者:天使没吃饱
  • 原文链接:https://blog.csdn.net/u011493599/article/details/70171977
    更新时间:2022年10月5日09:16:49 ,共 4679 字。