使用JdbcChannelMessageStore的QueueChannel序列化失败时无错误提示
Spring Integration事务性发件箱消息未入库排查与解决
问题现象
- 基于
QueueChannel+JdbcChannelMessageStore实现的事务性发件箱,消息始终无法存入数据库 - 替换为内存队列
MessageChannels.queue("test-queue")后功能完全正常 - 开启DEBUG日志仅能看到
preSend on channel日志,无postSend记录,控制台也未输出任何错误或堆栈信息
排查过程
通过在ChannelMessageStorePreparedStatementSetter.setValues()方法打断点调试,发现this.serializer.convert(requestMessage)抛出异常,提示消息未完全实现Serializable接口,且该异常被框架内部静默处理,未输出到日志,导致排查难度极大。
解决方案
确保消息体及所有嵌套对象完整实现Serializable接口,包括自定义的JmsMessage类及其内部所有成员变量对应的类。
相关配置代码
集成流程配置类
@Configuration public class JmsConfiguration { @Bean public DirectChannel jmsInput() { return new DirectChannel(); } @Bean public IntegrationFlow jmsOutboundFlow( JdbcChannelMessageStore jdbcChannelMessageStore, JmsMessenger jmsMessenger, JmsProperties properties, @Qualifier("springIntegrationTransactionInterceptor") TransactionInterceptor transactionInterceptor ) { return IntegrationFlow.from(this.jmsInput()) .channel(this.jmsOutbox(jdbcChannelMessageStore)) .handle(message -> { JmsMessage jmsMessage = (JmsMessage) message.getPayload(); jmsMessenger.sendMessage(jmsMessage); }, e -> e.poller(Pollers.fixedDelay(properties.outboxPollingDuration()) .transactional(transactionInterceptor))) .get(); } @Bean public QueueChannel jmsOutbox(JdbcChannelMessageStore jdbcChannelMessageStore) { return MessageChannels.queue(jdbcChannelMessageStore, "jms-outbox").getObject(); } }
消息触发网关
@MessagingGateway public interface JmsGateway { String JMS_INPUT_CHANNEL = "jmsInput"; @Gateway(requestChannel = JMS_INPUT_CHANNEL) void sendMessage(JmsMessage message); }
改进建议
建议Spring Integration在JdbcChannelMessageStore序列化消息失败时,至少输出警告级别的日志,避免异常被静默吞掉,降低问题排查成本。
内容的提问来源于stack exchange,提问作者Wim Deblauwe
相关产品推荐
相关产品推荐

