當我們調用一個接口可能由於網絡等原因造成第一次失敗,再去嘗試就成功了,這就是重試機制,spring支持重試機制,並且在Spring Cloud中可以與Hystaix結合使用,可以避免訪問到已經不正常的實例。
寫一個簡單的demo,加入依賴:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> </dependencies>
在主類上加上@EnableRetry注解,表示啟用重試機制。
@SpringBootApplication @EnableRetry public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
定義一個簡單的controller層:
@RestController public class HelloController { Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private PayService payService; @GetMapping("/createOrder") public String createOrder(@RequestParam int num) throws Exception{ int remainingnum = payService.minGoodsnum(num == 0 ? 1: num); logger.info("剩余的數量==="+remainingnum); return "庫庫存成功"; } }
在controller中調用減庫存的service接口,
@Service public class PayService { private Logger logger = LoggerFactory.getLogger(getClass()); private final int totalNum = 100000; @Retryable(value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5)) public int minGoodsnum(int num) throws Exception{ logger.info("minGoodsnum開始"+ LocalTime.now()); if(num <= 0){ throw new Exception("數量不對"); } logger.info("minGoodsnum執行結束"); return totalNum - num; } }
在minGoodsnum方法上加上@Retryable注解,value值表示當哪些異常的時候觸發重試,maxAttempts表示最大重試次數默認為3,delay表示重試的延遲時間,multiplier表示上一次延時時間是這一次的倍數。
測試:
圖片.png
圖片.png
重試三次拋出異常。
使用@Recover注解,當重試次數達到設置的次數的時候,還是失敗拋出異常,執行的回調函數。
關於@Recover注解
圖片.png
和minGoodsnum定義在一個類中
@Recover public int recover(Exception e){ logger.warn("減庫存失敗!!!"); //記日志到數據庫 return totalNum; }
重試測試一下,
圖片.png
感覺意義不大,重試失敗的時候應該還是要拋出異常的,在上層進行catch記錄日志,當然也有特殊的場景適用。
作者:二月_春風
鏈接:https://www.jianshu.com/p/314059943f1c
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。
