Spring異常重試框架Spring Retry


Spring Retry支持集成到Spring或者Spring Boot項目中,而它支持AOP的切面注入寫法,所以在引入時必須引入aspectjweaver.jar包。

快速集成的代碼樣例:

@Configuration
@EnableRetry public class Application {

    @Bean
    public Service service() {
        return new Service();
    }

}

@Service
class Service {
    @Retryable(RemoteAccessException.class) public service() {
        // ... do something
    }
}

下面是基於Spring Boot項目的集成步驟:

POM:

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

Service:

package com.jsoft.springboottest.springboottest1;

import java.time.LocalTime;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.remoting.RemoteAccessException;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
 @Service public class RemoteService {
    
    private final static Logger logger = LoggerFactory.getLogger(RemoteService.class);
    
    @Retryable(value = { RemoteAccessException.class }, maxAttempts = 3, backoff = @Backoff(delay = 5000l, multiplier = 1)) public void call() throws Exception {
        logger.info(LocalTime.now()+" do something...");
        throw new RemoteAccessException("RPC調用異常");
    }

    @Recover public void recover(RemoteAccessException e) {
        logger.info(e.getMessage());
    }
}

@Retryable注解

被注解的方法發生異常時會重試 

  • value:指定發生的異常進行重試 
  • include:和value一樣,默認空,當exclude也為空時,所有異常都重試 
  • exclude:指定異常不重試,默認空,當include也為空時,所有異常都重試 
  • maxAttemps:重試次數,默認3 
  • backoff:重試補償機制,默認沒有

@Backoff注解

  • delay:指定延遲后重試 
  • multiplier:指定延遲的倍數,比如delay=5000l,multiplier=2時,第一次重試為5秒后,第二次為10秒,第三次為20秒

@Recover 

當重試到達指定次數時,被注解的方法將被回調,可以在該方法中進行日志處理。需要注意的是發生的異常和入參類型一致時才會回調。

Controller:

package com.jsoft.springboottest.springboottest1.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.jsoft.springboottest.springboottest1.RemoteService;

@RestController
public class TestController {
    
    @Autowired
    private RemoteService remoteService;
    
    @RequestMapping("/show")
    public String show(){
        try {
            remoteService.call();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        return "Hello World";        
    }
}

App:

package com.jsoft.springboottest.springboottest1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;

/**
 * Hello world!
 *
 */
@SpringBootApplication
@EnableRetry public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

效果:

說明:

1、使用了@Retryable的方法不能在本類被調用,不然重試機制不會生效。也就是要標記為@Service,然后在其它類使用@Autowired注入或者@Bean去實例才能生效。

2、要觸發@Recover方法,那么在@Retryable方法上不能有返回值,只能是void才能生效。

3、使用了@Retryable的方法里面不能使用try...catch包裹,要在發放上拋出異常,不然不會觸發。

4、在重試期間這個方法是同步的,如果使用類似Spring Cloud這種框架的熔斷機制時,可以結合重試機制來重試后返回結果。

5、Spring Retry不只能注入方式去實現,還可以通過API的方式實現,類似熔斷處理的機制就基於API方式實現會比較寬松。

 

示例代碼:https://github.com/easonjim/5_java_example/tree/master/springboottest/springboottest3 

 

參考:

http://blog.csdn.net/u014513883/article/details/52371198(以上內容部分轉自此篇文章)

https://github.com/spring-projects/spring-retry(官網)

http://www.jianshu.com/p/314059943f1c

http://www.broadview.com.cn/article/233(熔斷重試)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM