重试的具体规定如下:
<bean id="retryAdvice"
class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice" >
<property name="retryTemplate">
<bean class="org.springframework.retry.support.RetryTemplate">
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="5000"/>
<property name="multiplier" value="3.0"/>
</bean>
</property>
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="6" />
</bean>
</property>
</bean>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
我预计每次尝试时间间隔都会增加3倍.实际上我得到了以下间隔:5,15,30,30,30秒.请参阅下面的确切时间和间隔.我错误地指定了什么?
2016-05-10 10:07:49,714 - 0
2016-05-10 10:07:55,085 - 5.2
2016-05-10 10:08:10,457 - 15.4
2016-05-10 10:08:40,830 - 30.4
2016-05-10 10:09:11,230 - 30.4
2016-05-10 10:09:41,639 - 30.4
Run Code Online (Sandbox Code Playgroud) 我试图将最简单的重试方案归结为可能.执行时会忽略重试.
Application.java:
@SpringBootApplication
@EnableRetry
public class Application extends SpringBootServletInitializer {
//...
Run Code Online (Sandbox Code Playgroud)
这是在Service类中:
public Boolean processItem() {
Long id = 999L;
try {
retrieveItemWithRetry(id);
return true;
} catch (NoResultException e) {
return false;
}
}
@Retryable(include=NoResultException.class, backoff = @Backoff(delay = 500, maxDelay = 3000), maxAttempts = 5)
private void retrieveItemWithRetry(Long id) {
retrieveItem(id);
}
private OrderRequest retrieveItem(Long id) {
throw new NoResultException();
}
Run Code Online (Sandbox Code Playgroud) 我想用Spring Retry修改数据库连接的创建,以便在应用程序启动时数据库关闭时再试一次。我不想限制重试次数。我应该如何配置策略来做到这一点。
我当前的代码(我知道在这种状态下它限制为100):
SimpleRetryPolicy policy = new SimpleRetryPolicy(100, Collections.singletonMap(Exception.class, true));
// Use the policy...
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(policy);
Connection conn = template.execute(new RetryCallback<Connection, Exception>() {
public Connection doWithRetry(RetryContext context) throws Exception {
return getConnectionFactory().createConnection();
}
});
Run Code Online (Sandbox Code Playgroud)
我应该如何修改此代码?
我的工作,我已经使用了Spring Batch的应用RetryTemplate有SimpleRetryPolicy。
在此应用程序中,ItemProcessor通常需要30-35分钟才能完成特定任务。但是有时候,完成同一任务需要不到2个小时。
ItemProcessor如果分配的任务在给定时间内未完成,是否可以重试我的方法?
我正在寻找一些Java / Spring内置功能,而不是编写自己的超时逻辑。
spring spring-batch spring-retry retrypolicy spring-batch-job-monitoring
我在用 spring boot 做 spring-retry 时发现了一个问题。类实现接口时,超过最大重试次数后无法进入@recover方法。但是当我注入一个普通的类时,我可以进入这个方法。您的及时帮助和善意的建议将不胜感激,谢谢!
当我这样做时,我可以进入@Recover 方法
@Service
public class TestService {
@Retryable(Exception.class)
public String retry(String c) throws Exception{
throw new Exception();
}
@Recover
public String recover(Exception e,String c) throws Exception{
System.out.println("got error");
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
但是一旦类实现了另一个接口,它就不起作用了
@Service
public class TestService implements TestServiceI{
@Override
@Retryable(Exception.class)
public String retry(String c) throws Exception{
throw new Exception();
}
@Recover
public String recover(Exception e,String c) throws Exception{
System.out.println("got error");
return null;
}
}
Run Code Online (Sandbox Code Playgroud) 我想为 spring 重试编写一个 junit 测试用例,我尝试了如下,但 junit 没有按预期工作。我正在调用 MaxAttemptRetryService.retry 方法,如果失败,它必须尝试最多 3 次。在这里,Dao 正在调用一个休息服务,该服务已关闭,因此它应该最多尝试 3 次。因此dao.sam方法必须被调用3次。
服务等级:
@Service
@EnableRetry
public class MaxAttemptRetryService {
@Retryable(maxAttempts=3)
public String retry(String username) throws Exception {
System.out.println("retry???? am retrying...");
int h = maxAttemptDao.sam();
return "kkkk";
}
}
Run Code Online (Sandbox Code Playgroud)
道类:
@Component
public class MaxAttemptDao {
public int sam() throws Exception{
try{
new RestTemplate()
.getForObject("http://localhost:8080/greeting1/{userName}",
String.class, "");
}catch(Exception e){
throw e;
}
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
测试类:
@RunWith(SpringRunner.class)
public class HystrixServiceTest {
@InjectMocks
private MaxAttemptRetryService maxAttemptRetryService = new MaxAttemptRetryService();
@Mock …Run Code Online (Sandbox Code Playgroud) 我将 Spring Boot1.4.0.RELEASE与spring-boot-starter-batch,spring-boot-starter-aop和spring-retry
我有一个 Spring 集成测试,其中有一个@Service在运行时被模拟的。我注意到,如果该类在其方法上@Service包含任何@Retryable注释,那么它似乎会干扰Mockito.verify(),我得到一个UnfinishedVerificationException. 我想这一定与什么有关spring-aop?如果我注释掉@Retryable中的所有注释,@Service则验证工作再次正常。
我创建了一个github 项目来演示这个问题。
它失败sample.batch.MockBatchTestWithRetryVerificationFailures.batchTest()于validateMockitoUsage();
像这样的东西:
12:05:36.554 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@5ec0a365 testClass = MockBatchTestWithRetryVerificationFailures, testInstance = sample.batch.MockBatchTestWithRetryVerificationFailures@5abca1e0, testMethod = batchTest@MockBatchTestWithRetryVerificationFailures, testException = org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
-> at sample.batch.service.MyRetryService$$FastClassBySpringCGLIB$$7573ce2a.invoke(<generated>)
Example of correct verification:
verify(mock).doSomething()
Run Code Online (Sandbox Code Playgroud)
不过,我有另一个类( ) ,它带有一个没有任何注释的sample.batch.MockBatchTestWithNoRetryWorking.batchTest()模拟类,并且验证工作正常。 …
我正在使用基于注释的方法 -@Retryable在 Spring Boot 应用程序中重试。
@Retryable(value = {DataAccessException.class, JpaSystemException.class}, maxAttempts = Integer.MAX_VALUE, backoff = @Backoff(delay = 30000))
Run Code Online (Sandbox Code Playgroud)
我想要做的是,每次重试时,我都想访问其当前的重试尝试。
我尝试使用 Java 反射来执行此操作 -
Retryable retryable = mth.getAnnotation(Retryable.class);
Run Code Online (Sandbox Code Playgroud)
但是使用这个我没有得到当前的重试尝试。它只是提供添加到@Retryable属性中的详细信息,例如value, maxAttempts, Backoffdetails
对此有什么想法吗?非常感谢帮助。
我正在连接到 Azure SQL 数据库,下一个任务是在连接失败时创建自定义重试逻辑。我希望重试逻辑在启动时(如果需要)以及应用程序运行时出现连接失败时运行。我做了一个测试,从我的应用程序中删除了 IP 限制,然后导致我的应用程序出现异常(如例外)。我想在抛出该异常时进行处理,以便我可以触发一个作业来验证应用程序和服务器是否配置正确。我正在寻找一种可以处理这些异常并重试数据库事务的解决方案?
数据源配置
@Bean
@Primary
public DataSource dataSource() {
return DataSourceBuilder
.create()
.username("username")
.password("password")
.url("jdbc:sqlserver://contoso.database.windows.net:1433;database=*********;user=******@*******;password=*****;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;")
.driverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver")
.build();
}
Run Code Online (Sandbox Code Playgroud)
应用程序属性
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
spring.jpa.show-sql=true
logging.level.org.springframework.web: ERROR
logging.level.org.hibernate: ERROR
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=1
spring.datasource.tomcat.test-on-borrow=true
spring.jpa.hibernate.ddl-auto=update
Run Code Online (Sandbox Code Playgroud) spring-data spring-data-jpa spring-retry hikaricp azure-sql-database
webclientbuilder.baseUrl(url)
.defaultHeaders(headers -> headers.addAll(requestHeader))
.build()
.post()
.uri("/uri")
.bodyValue(data)
.exchange()
.flatMap(response -> {
if(response.statusCode() == HttpStatus.UNAUTHORIZED){
//retry with updated token in header
}
})
//return bodyToMono of specific object when retry is done or if
//response status is 2xx
Run Code Online (Sandbox Code Playgroud)
任何有关如何处理此问题的建议将不胜感激!正如评论所说,如果 statusCode 为 UNAUTHORIZED,并且如果 statusCode 为 2xx,则在重试 post 请求之前,我需要将新令牌添加到标头,然后返回 bodyToMono。
spring request-headers spring-retry spring-boot spring-webclient
spring-retry ×10
spring ×7
spring-boot ×4
java ×3
spring-batch ×2
hikaricp ×1
jdbc ×1
junit ×1
mockito ×1
retrypolicy ×1
spring-aop ×1
spring-batch-job-monitoring ×1
spring-data ×1