Spring boot JMS:当JMS接收器发生内部应用程序错误时,如何不丢失jms消息

问题描述 投票:0回答:1

如果JMS接收器由于数据库连接失败等原因而失败,那么JMS消息将丢失。有人可以建议我,什么是常见的解决方案,以避免在Spring Boot应用程序中丢失JMS消息]

在接收方处理消息时,如果发生错误,我是否应该将消息重新发送回它起源的队列?

这是我的脚本源代码。

@SpringBootApplication
public class MainApp {

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

    @Bean
    public JmsListenerContainerFactory<?> sdbFactory(ConnectionFactory connectionFactory,
                                                    DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        // This provides all boot's default to this factory, including the message converter
        configurer.configure(factory, connectionFactory);
        // You could still override some of Boot's default if necessary.
        return factory;
    }

    @Bean
    public Queue queue() {
        return new ActiveMQQueue("sdb.orderQueue");
    }



    @Bean
    public MessageConverter jacksonJmsMessageConverter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.TEXT);
        converter.setTypeIdPropertyName("_type");
        return converter;
    }

    @Bean
    public ModelMapper mapper() {
        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        return mapper;
    }

}

生产者

@RestController
@RequestMapping("/transaction")
public class OrderTransactionController {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

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

    @PostMapping("/send")
    public void send(@RequestBody OrderDTO order)  {
        LOGGER.info("Sending a transaction."+ order);
        jmsMessagingTemplate.convertAndSend("sdb.orderQueue", order);
    }
}

消费者

@Component
public class OrderMessageReceiver {

    @Autowired
    OrderService service;

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

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

    @JmsListener(destination = "sdb.orderQueue", containerFactory = "sdbFactory")
    public void receiveQueue(OrderDTO order) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        ModelMapper modelMapper = new ModelMapper();

        OrderEntity orderEntity = modelMapper.map(order, OrderEntity.class);
        try {
            service.createOrder(orderEntity);
        } catch (Exception e) {
            LOGGER.error("Error happend while trying to persist order : {} error is : {}",order, e);


        }
    }


}
spring-boot jms message-queue spring-jms
1个回答
1
投票

您需要显示如何使用它以及配置,但是默认情况下,使用DefaultMessageListenerContainer时会话将为transacted,因此,如果侦听器向容器抛出异常,则事务将回滚并且消息添加回队列。

如果侦听器正常退出,则事务将提交并删除消息。

© www.soinside.com 2019 - 2024. All rights reserved.