当前位置: 首页 > 知识库问答 >
问题:

SpringBootJMS:如何在JMS接收器发生内部应用程序错误时不丢失JMS消息

柳镜
2023-03-14

若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);


        }
    }


}

共有1个答案

洪德寿
2023-03-14

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

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

 类似资料:
  • 到目前为止我有下一个: 我被“已发送消息”困住了。看起来子请求没有真正发送。我在MQ UI中看到队列深度为1,但内部没有消息,并且我的子请求侦听器也没有看到任何消息。 我还尝试使用方法: 启用事务开始/结束日志也很有帮助:

  • 我正在开发一个使用JMS作为消息传递层的应用程序。我还使用glassfish来托管jms/mq后端。该应用程序能够使用我最初设置的glassfish 3.1服务器中的连接工厂和主题进行发布/订阅消息传递。我现在有了glassfish (4.1)的另一个实例,它托管了一组新的应用程序使用的新功能,但是我仍然需要使用第一个glassfish服务器广播的消息。事实上,客户端使用特定于glassfish

  • 我错过了什么? AMQ版本5.13.2 Java 1.8.0\u 74 Windows 10 给定一个简单的测试用例,传输两条Object消息,一条带有数据,另一条是数据结束标记。只有数据结束标记被接收。 队列在作业开始时创建,并在作业完成后销毁。 如果我运行更多的事务,我会看到大约50%的接收率。 日志清楚地显示接收器在第一条消息被放入队列之前就已启动,两条消息都被放入队列,但实际上只有第二条消

  • 我已经用Apache ActiveMQ和一个简单的应用程序创建了一个JMS代理,该应用程序将消息纳入队列OK。 我想创建另一个简单的应用程序,使用MDP异步出列这些消息。以下是我到目前为止所拥有的一个例子: 现在我大概需要一个main方法,但是如果消息到达队列时监听器会异步调用onMessage方法,我不确定如何编写代码: 谢谢你的帮助。

  • 因此,我使用Spring integration链接JMS和ActiveMQ,如下所示:- 如何使其工作,以便发送到此队列并从中接收消息?请帮忙。