如何解决Spring Boot失败时不会重试SQS JMS消息
给出这样的JMS / SQS配置:
private final SQSConnectionFactory sqsConnectionFactory = new SQSConnectionFactory(
new ProviderConfiguration().withNumberOfMessagesToPrefetch(10),AmazonSQSClientBuilder.defaultClient());
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(this.sqsConnectionFactory);
factory.setDestinationResolver(new DynamicDestinationResolver());
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
return factory;
}
和这样的接收器:
@Service
public class HandleMessage {
@Transactional
@JmsListener(destination = "${sqs.handler}")
public void receive(String message) throws IOException,JMSException {
...
if (message.contains("test"))
throw new JMSException("boom!");
...
}
我发现所有消息都在处理中,并且包含测试的消息消失了,而不是重试。在SQS配置中是否可能需要更改某些内容。
@Transactional
属性可能是必需的,也可能不是必需的,但是我想要的是Spring Boot在出现异常的情况下向SQS发出消息失败的信号,我确信这是可能的。
Maximum message size 256 KB
Last updated 5/25/2020,12:00:10
Message retention period 4 Days
Default visibility timeout 30 Seconds
Messages available 0
Delivery delay 0 Seconds
Messages in flight (not available to other consumers) 0
Receive message wait time 0 Seconds
Messages delayed 0
Content-based deduplication -
解决方法
我希望这能回答您的问题,或者至少使您朝正确的方向前进。
您将需要将JTA事务管理器部署为Spring PlatformTransactionManager。有很多可用的工具,我在Arjuna上取得了不错的成绩。添加启动器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-narayana</artifactId>
</dependency>
将部署Arjuna并将其配置为PlatformTransactionManager。
有用的日志记录:
<logger name="com.arjuna" level="TRACE" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
丢弃:
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
并添加:
factory.setSessionTransacted(true);
当消息侦听器容器开始侦听消息时,它应该创建一个事务上下文。当您使用事务方法时,该方法应加入事务上下文。如果该方法的提交成功,那么您应该在Arjuna日志中看到消息receive get commit。如果存在异常,则侦听器事务将被回滚,并且您的消息将返回到您的队列。
只是要弄混水...。您只有一个事务性资源-JMS会话。您可以避免使用完整的JTA事务管理器。我个人认为它们不会占用过多的资源。您可以创建一个JmsTransactionManager,并将连接工厂传递到其中。然后,可以将消息侦听器容器工厂上的JmsTransactionManager设置为事务管理器。
,我实际上解决了这个问题,这很令人尴尬。
我真的很喜欢上述答案中的所有建议,并已将其标记为正确,因为在某些情况下加入交易将带来巨大好处。
但是对于那些可能会偶然发现此问题的人,谨在此提醒您,以确保星球上某处(在我的情况下为另一大洲)没有其他服务器在消耗该服务器。失败的消息。
一旦我确定自己是地球上唯一一个收听消息的机器,便得到了所有希望得到的重试。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。