Spring 引导 JMS:当 JMS 接收器发生内部应用程序错误时如何不丢失 jms 消息
Spring boot JMS : How not to lose jms message when internal application error happens at the JMS receiver
如果JMS 接收方由于某些原因(例如数据库连接失败)而失败,那么JMS 消息将丢失。谁能建议我避免使用 spring 启动应用程序
丢失 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
因此如果侦听器向容器抛出异常事务将回滚并将消息添加回队列。
如果侦听器正常退出,事务将提交并删除消息。
如果JMS 接收方由于某些原因(例如数据库连接失败)而失败,那么JMS 消息将丢失。谁能建议我避免使用 spring 启动应用程序
丢失 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
因此如果侦听器向容器抛出异常事务将回滚并将消息添加回队列。
如果侦听器正常退出,事务将提交并删除消息。