标签: spring-retry

@Retryable在Spring引导应用程序中由集成测试触发时不进行重试

我在SpringBoot应用程序的Service中有一个简单的方法.我使用@Retryable为该方法设置了重试机制.
我正在尝试对服务中的方法进行集成测试,并且在方法抛出异常时不会发生重试.该方法只执行一次.

public interface ActionService { 

@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 2000))
public void perform() throws Exception;

}



@Service
public class ActionServiceImpl implements ActionService {

@Override   
public void perform() throws Exception() {

   throw new Exception();
  } 
}



@SpringBootApplication
@Import(RetryConfig.class)
public class MyApp {

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



@Configuration
@EnableRetry
public class RetryConfig {

@Bean
public ActionService actionService() { return new ActionServiceImpl(); }

}



@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration( classes= {MyApp.class}) 
@IntegrationTest({"server.port:0", "management.port:0"})
public …
Run Code Online (Sandbox Code Playgroud)

java spring spring-retry spring-boot

5
推荐指数
1
解决办法
8470
查看次数

使用spring-amqp和rabbitmq通过退回实现无阻塞重试

我正在寻找一种使用spring amqp和Rabbit MQ通过后退策略实现重试的好方法,但是要求是不应该阻止侦听器(因此可以自由处理其他消息)。我在此处看到了类似的问题,但其中不包含“退缩”的解决方案:

RabbitMQ和Spring amqp重试时不会阻止使用者

我的问题是:

  1. 默认的spring-retry实现会在重试时阻止线程吗?github中实现表明确实如此。

  2. 如果上述假设是正确的,那么这是唯一的实现此方法的方法,即实现一个单独的重试队列(DLQ?),并为每条消息设置一个TTL(假设我们不想在退避间隔内阻塞线程)。

  3. 如果我们采用上述方法(DLQ或单独的队列),那么每次重试尝试是否都不需要单独的队列?如果仅使用1个队列进行重试,则同一队列将包含TTL范围从最小重试间隔到最大重试间隔的消息,并且如果队列前面的消息具有最大TTL,则后面的消息将不会即使它具有最小TTL也会拾取。这是根据此处的Rabbit MQ TTL文档(请参见警告):

  4. 还有另一种方法来实现无阻塞的重试机制吗?

添加一些配置信息以帮助对@garyrussel进行故障排除:

队列配置:

    <rabbit:queue name="regular_requests_queue"/>
    <rabbit:queue name="retry_requests_queue">
        <rabbit:queue-arguments>
            <entry key="x-dead-letter-exchange" value="regular_exchange" />
        </rabbit:queue-arguments>
    </rabbit:queue>

    <rabbit:direct-exchange name="regular_exchange">
        <rabbit:bindings>
            <rabbit:binding queue="regular_requests_queue" key="regular-request-key"/>
        </rabbit:bindings>
    </rabbit:direct-exchange>

    <rabbit:direct-exchange name="retry_exchange">
        <rabbit:bindings>
            <rabbit:binding queue="retry_requests_queue"/>
        </rabbit:bindings>
    </rabbit:direct-exchange>

    <bean id="retryRecoverer" class="com.testretry.RetryRecoverer">
         <constructor-arg ref="retryTemplate"/>
         <constructor-arg value="retry_exchange"/>
    </bean>

    <rabbit:template id="templateWithOneRetry" connection-factory="connectionFactory" exchange="regular_exchange" retry-template="retryTemplate"/>
    <rabbit:template id="retryTemplate" connection-factory="connectionFactory" exchange="retry_exchange"/>

    <bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
        <property name="retryPolicy">
            <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                <property name="maxAttempts" value="1"/>
            </bean>
        </property>
    </bean>
Run Code Online (Sandbox Code Playgroud)

rabbitmq spring-amqp spring-retry

5
推荐指数
1
解决办法
2159
查看次数

注释不起作用的Spring重试框架

我使用SimpleRetryPolicy/RetryTemplate尝试使用Simple java类的spring retry框架.它工作正常.所以我想用Annotations做同样的事情.注释从来没有对我有用.在网上找不到太多帮助.下面的代码就像普通的Java程序一样,在第一次尝试时抛出异常,这不是预期的行为.在抛出异常或从中恢复之前,它应该至少试过5次.不知道我哪里出错了.我是否需要执行任何XML/spring AOP配置才能工作?怎么会这样

import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;

@EnableRetry
@Configuration
public class App {  
    public static void main(String[] args) throws Exception {
        Parentservice p = new  SpringRetryWithHystrixService();
        String status = p.getStatus();
        System.out.println(status);
    }
}

import org.springframework.retry.annotation.Retryable;
public interface Parentservice {
    @Retryable(maxAttempts=5)
    String getStatus() throws Exception;
}


import org.springframework.retry.annotation.Recover;
public class SpringRetryWithHystrixService implements Parentservice{

    public static int i=0;

    public String getStatus() throws Exception{
        System.out.println("Attempt:"+i++);
        throw new NullPointerException();
    }

        @Recover
        public static String getRecoveryStatus(){
            return "Recovered from NullPointer Exception";
        }
    }
Run Code Online (Sandbox Code Playgroud)

我在界面和实现的顶部尝试了@Retryable(maxAttempts …

java spring-retry

5
推荐指数
1
解决办法
3469
查看次数

Spring Retry @Recover传递参数

我找不到任何有关需要采取行动的信息。我正在使用@Retryable注释和@Recover处理程序方法。像这样:

    @Retryable(value = {Exception.class}, maxAttempts = 5, backoff = @Backoff(delay = 10000))
    public void update(Integer id)
    {
        execute(id);
    }

    @Recover
    public void recover(Exception ex)
    {
        logger.error("Error when updating object with id {}", id);
    }
Run Code Online (Sandbox Code Playgroud)

问题是我不知道如何将我的参数“ id”传递给recovery()方法。有任何想法吗?提前致谢。

java spring recover spring-retry

5
推荐指数
1
解决办法
4532
查看次数

Spring @EnableRetry抛出InternalAutoProxyCreator

我创建了示例Spring-boot应用程序,它运行正常,没有任何错误,

现在我想练习spring-retry重试一些方法。如果我不使用,@EnableRetry我的应用程序启动时将没有任何错误,但重试无法正常进行。

如果我@EnableRetry在配置类上使用,我的应用程序无法启动

build.gradle

apply plugin: 'java-library'

repositories {
  jcenter()
  }

 dependencies {

        // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
         compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.0.RELEASE'
        // https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka
         compile group: 'org.springframework.kafka', name: 'spring-kafka', version: '2.2.0.RELEASE'
        // https://mvnrepository.com/artifact/commons-logging/commons-logging
         compile group: 'commons-logging', name: 'commons-logging', version: '1.2'
         // https://mvnrepository.com/artifact/org.springframework.retry/spring-retry
         compile group: 'org.springframework.retry', name: 'spring-retry', version: '1.2.0.RELEASE'

}
Run Code Online (Sandbox Code Playgroud)

设定档

import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;

@Configuration
@EnableRetry
public class RetryConfig {

 }
Run Code Online (Sandbox Code Playgroud)

重试服务

@Service
public class RetryService {

 @Retryable(value = { CustomException.class …
Run Code Online (Sandbox Code Playgroud)

java spring aspectj spring-retry spring-boot

5
推荐指数
1
解决办法
1533
查看次数

如何使用Spring重试PostgreSQL可序列化事务?

我正在针对PostgreSQL v12数据库进行开发。我正在使用SERIALIZABLE交易。一般想法是,当PostgreSQL检测到序列化异常时,应重试完整的事务。

我正在使用Spring的AbstractFallbackSQLExceptionTranslator将数据库异常转换为Spring的异常类。此异常翻译器应将PostgreSQL错误40001/serialization_failure转换为ConcurrencyFailureException。Spring JDBC维护一个映射文件,以将PostgreSQL特定的代码映射到数据库异常40001的通用cannotSerializeTransactionCodes类,该类将转换ConcurrencyFailureException为API用户。

我的想法是依靠Spring Retry项目重试SERIALIZABLE由于序列化错误而暂停的事务,如下所示:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Retryable(include = ConcurrencyFailureException.class, maxAttempts = ..., backoff = ...)
@Transactional(isolation = Isolation.SERIALIZABLE)
public @interface SerializableTransactionRetry {
}
Run Code Online (Sandbox Code Playgroud)

在服务实现,我会简单地替换@Transactional通过@SerializableTransactionRetry,并用它做。

现在,回到PostgreSQL。本质上,可以在两个阶段检测序列化异常:

  1. 在执行语句期间
  2. 在事务的提交阶段

似乎Spring AbstractFallbackSQLExceptionTranslator正确地转换了在执行语句期间检测到的序列化异常,但在提交阶段未能转换序列化异常。考虑以下堆栈跟踪:

org.springframework.transaction.TransactionSystemException: Could not commit JDBC transaction; nested exception is org.postgresql.util.PSQLException: ERROR: could not serialize access due to read/write dependencies among …
Run Code Online (Sandbox Code Playgroud)

postgresql spring transactions spring-jdbc spring-retry

5
推荐指数
1
解决办法
63
查看次数

如何在SpringBootTest中模拟Spring的@Retryable属性,例如maxAttemps和delay

我有一个正在尝试测试的方法

@Retryable(value = {SocketTimeoutException.class},
             backoff = @Backoff(delay = 10000),
             maxAttempts = 4)
public String getNewString(String oldString) throws IOException{
   ...
}
Run Code Online (Sandbox Code Playgroud)

我已经创建了它的测试用例,如下所示:

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestStrings {
  @Test(expected = SocketTimeoutException.class)
  public void testGetNewString() throws IOException {
     ...
  }
Run Code Online (Sandbox Code Playgroud)

一切运行良好,测试用例运行 4 次,延迟 10 秒。但我想更改@Retryable的属性,即对于这个特定的测试用例,maxAttempts从4到2,延迟从10s到0.5s。我想这样做,以便在运行测试用例时不应该等待很长时间,并且测试用例应该快速结束,同时还测试重试功能。

java spring mockito spring-retry spring-boot

5
推荐指数
1
解决办法
931
查看次数

Spring AMQP StatefulRetryOperationsInterceptor未使用

我正在尝试配置spring amqp只重试一次消息定义的次数.目前,例如由于a而失败的消息DataIntegrityViolationException 被无限期地重新传递.

根据这里的文档,我提出了以下配置

@Bean
    public StatefulRetryOperationsInterceptor statefulRetryOperationsInterceptor() {
        return RetryInterceptorBuilder.stateful()
                .backOffOptions(1000, 2.0, 10000) // initialInterval, multiplier, maxInterval
                .maxAttempts(3)
                .messageKeyGenerator(message -> UUID.randomUUID().toString())
                .build();
    } 
Run Code Online (Sandbox Code Playgroud)

这似乎没有应用 - 消息仍然无限期地尝试.

感觉就像我在这里遗漏了一些东西.

以下是关于AMQP的剩余配置:

@Bean
    Queue testEventSubscriberQueue() {
        final boolean durable = true;
        return new Queue("testEventSubscriberQueue", durable);
    }

    @Bean
    Binding binding(TopicExchange topicExchange) {
        return BindingBuilder.bind(testEventSubscriberQueue()).to(topicExchange).with("payload.event-create");
    }

    @Bean
    SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(testEventSubscriberQueue().getName());
        container.setMessageListener(listenerAdapter);
        container.setChannelTransacted(true);
        return container;
    }


    @Bean
    MessageListenerAdapter listenerAdapter(MessageConverter messageConverter, SubscriberHandler …
Run Code Online (Sandbox Code Playgroud)

java spring rabbitmq spring-amqp spring-retry

4
推荐指数
1
解决办法
1119
查看次数

Spring Retry:未调用带有@Recover注释的方法

我正在测试春季重试,但似乎没有被称为恢复。试图使其工作,但似乎无遗。我没有给@Recover传递任何参数Throwable Exception。更改了重试依赖项版本,似乎它已包含在aop中以用于春季启动并已将其删除。不会通过以下异常消息来调用保持恢复状态。

请求处理失败;嵌套的异常是org.springframework.retry.ExhaustedRetryException:无法找到恢复方法。嵌套异常是java.lang.ArithmeticException:/按零],其根本原因是

任何帮助将非常感激

我的代码如下所示。

配置类

package hello;

import java.util.Arrays;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;

@SpringBootApplication
@EnableRetry
public class Application {
public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {

        System.out.println("Let's inspect the beans provided by `Spring Boot:");`

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

    };
}

}
Run Code Online (Sandbox Code Playgroud)

休息控制器类;

package hello;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired; …
Run Code Online (Sandbox Code Playgroud)

java aop spring-retry spring-boot

4
推荐指数
2
解决办法
4545
查看次数

Spring Retry - 异常问题和重试

我们如何在同一个方法块中捕获两个不同的异常(例如来自.lang和包) 。其一,我们返回一个,另一个我们重试该方法。.io@RetryableIOException

@Retryable(value = {Exception.calss } ,maxAttempts = 3, backoff = @Backoff(delay = 3000))
public String getInfo() {
    try {
        //here we have an executive code that may have an IOException
    } catch(Exception ex) {
        //And here i would catch the Exception 
        throw new Exception();
    }   
}
Run Code Online (Sandbox Code Playgroud)

java spring exception spring-retry spring-boot

4
推荐指数
1
解决办法
4546
查看次数