gpt4 book ai didi

java - 为发布者实现 Spring Retry 逻辑有困难

转载 作者:行者123 更新时间:2023-12-02 02:35:22 26 4
gpt4 key购买 nike

我有一个带有 JMS 发布器的 Spring Boot 应用程序。发布者使用发布者类中的重试逻辑,效果很好。但我想将其更改为 Spring Retry Template 并将其放入连接工厂配置中。

我无法弄清楚如何调用将 RetryTemplate 添加到 Publisher 类中。

这是配置类:

@Configuration
@EnableRetry
public class PurchasedTransServicePublisherConfig {

@Value("${java.naming.factory.initial.publisher}")
private String context;

@Value("${java.naming.provider.url.publisher}")
private String providerURL;

@Value("${fedex.jms.LDAP.entryName.publisher}")
private String ldapEntryName;

private @Value("${jms.username.publisher:#{null}}") String jmsUserName;
private @Value("${jms.password.publisher:#{null}}") String jmsPassword;

@Value("${jms.destinationname.publisher}")
private String destinationName;

private static final Logger LOGGER = LoggerFactory.getLogger(PurchasedTransServicePublisherConfig.class);

@Autowired(required = false)
FxgCipherInitializer jmsParams;

@Bean
public JmsTemplate publisherJmsTemplate(final ConnectionFactory publisherConnectionFactory) {
final JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(publisherConnectionFactory);
jmsTemplate.setPubSubDomain(true);
jmsTemplate.setDefaultDestinationName(destinationName);
jmsTemplate.setSessionTransacted(true);
return jmsTemplate;
}

@Bean
public ConnectionFactory publisherConnectionFactory(final JndiTemplate publisherJndiTemplate) throws NamingException {
final ConnectionFactory connectionFactory = (ConnectionFactory) publisherJndiTemplate.getContext().lookup(ldapEntryName);
final UserCredentialsConnectionFactoryAdapter ucf = new UserCredentialsConnectionFactoryAdapter();
ucf.setUsername(((null != jmsParams) ? jmsParams.getUsername() : jmsUserName));
ucf.setPassword((null != jmsParams) ? jmsParams.getPassword() : jmsPassword);
ucf.setTargetConnectionFactory(connectionFactory);
return ucf;
}

@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(2000l);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(2);
retryTemplate.setRetryPolicy(retryPolicy);
return retryTemplate;
}


@Bean
public JndiTemplate publisherJndiTemplate() {
final JndiTemplate jndiTemplate = new JndiTemplate();
final Properties jndiProps = new Properties();
jndiProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, context);
jndiProps.setProperty(Context.PROVIDER_URL, providerURL);
jndiTemplate.setEnvironment(jndiProps);
return jndiTemplate;
}
}

工作配置和 RetryTemplate 配置之间的唯一变化是添加了注释 @EnableRetry 和方法 retryTemplate

发布者类最初使用以下逻辑成功重试发送消息:

 private void send(final MessageCreator messageCreator) throws JMSException {
int sendAttempts = 0;

while (true) {
try {
jmsTemplate.send(messageCreator);
LOGGER.info("Message Successfully Published");
break;
} catch (RuntimeException e) {
LOGGER.error("Caught Runtime Exception: {}", e.getMessage());
sendAttempts++;
handleJmsExceptionRetry(e, sendAttempts);
}
}
}

我尝试像这样实现重试模板:

 private void send(final MessageCreator messageCreator) throws JMSException {
while (true) {
try {
publisherJmsTemplate.send(messageCreator);
LOGGER.info("Message Successfully Published");
break;
} catch (RuntimeException e) {
LOGGER.error("Caught Runtime Exception: {}", e.getMessage());
publisherRetryTemplate.execute(arg0 -> {
publisherJmsTemplate.send(messageCreator);
return null;
});
}
}
}

我创建的用于单元测试的测试方法如下:

 @Test
public void testPublishTmsTrip_WhenPublishFailsMultipleTimes() {
Mockito.doThrow(RuntimeException.class).when(mockJmsTemplate).send(mockMessageCreator);
boolean testBoolean = tmsTripPublisher.publishTmsTripMessageEvent("TEST message");
assertFalse(testBoolean);
}

问题是当它到达 publisherRetryTemplate.execute... 时,它不会执行 RetryTemplate 方法。任何有关如何实现此重试逻辑的指导将不胜感激。

最佳答案

除非您在方法上使用@Retryable,否则不需要@EnableRetry

不清楚为什么你有 while (true) ,或者为什么你最初在重试模板的执行方法之外调用。

为什么不只是

private void send(final MessageCreator messageCreator) throws JMSException {
publisherRetryTemplate.execute(arg0 -> {
publisherJmsTemplate.send(messageCreator);
return null;
});
}

不清楚“它不执行 RetryTemplate 方法”是什么意思。

关于java - 为发布者实现 Spring Retry 逻辑有困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57207202/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com