转载:http://blog.csdn.net/u011493599/article/details/70171977
2、模拟网络异常,创建一个异常
4、在service模拟访问异常,抛出异常
说明:
在调用第三方接口或者使用mq时,会出现网络抖动,连接超时等网络异常,所以需要重试。
1、引入jar包
- <dependency>
- <groupId>org.springframework.retry</groupId>
- <artifactId>spring-retry</artifactId>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjweaver</artifactId>
- </dependency>
<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;
- }
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 {
@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”;
- }
- }
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;
- }
@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;
- }
- }
- }
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
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
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