如果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);
}
}
}
您需要显示如何使用它以及配置,但是默认情况下,使用DefaultMessageListenerContainer
时会话将为transacted
,因此,如果侦听器向容器抛出异常,则事务将回滚并且消息添加回队列。
如果侦听器正常退出,则事务将提交并删除消息。