我们正在使用来自HiveMQ MQTT Broker的消息,并使用spring集成处理数据。作为最后的处理步骤,我们通常使用int-jpa:outbound-channel-adapter在关系数据库上执行update / insert语句。
让我们考虑数据库连接丢失但入站mqtt adataper仍然使用mqtt消息的情况。目前我们丢失了这些消息,因为我们没有处理失败的数据库操作。
如果数据库连接当前不可用,我们应该如何处理消息?
我们是否应该实现一个由另一个高可用性数据库支持的消息存储库,该数据库持久保存来自spring集成的消息?
我们应该实施重试建议并定期重试数据库操作吗?
作为我们的出发点,我们尝试使用以下spring-context.xml实现重试建议。结果,消息被重试一次,然后由于无法执行数据库操作而发生异常。发生异常后没有再执行重试。
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int-jpa="http://www.springframework.org/schema/integration/jpa"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jpa http://www.springframework.org/schema/integration/jpa/spring-integration-jpa.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<int:channel id="mqttInputChannel" />
<!-- MQTT INBOUND ADAPTER IS CONFIGURED IN JAVA -->
<int-jpa:outbound-channel-adapter
channel="mqttInputChannel"
flush-size=""
entity-class="com.iot.db.DefaultBean"
persist-mode="PERSIST"
entity-manager-factory="entityManagerFactory">
<int-jpa:transactional transaction-manager="transactionManager" />
<int-jpa:request-handler-advice-chain>
<ref bean="retryAdvice" />
</int-jpa:request-handler-advice-chain>
</int-jpa:outbound-channel-adapter>
<int:handler-retry-advice id="retryAdvice" />
</beans>
另一种方法是通过消息存储备份消息,但我们无法将消息存储绑定到jpa适配器事务。以下是带有消息存储的相应spring-context.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int-jpa="http://www.springframework.org/schema/integration/jpa"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jpa
http://www.springframework.org/schema/integration/jpa/spring-integration-jpa.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<int:channel id="mqttInputChannel">
<int:queue message-store="messageStore" />
</int:channel>
<bean
id="messageStore"
class="org.springframework.integration.jdbc.store.JdbcChannelMessageStore">
<property
name="dataSource"
ref="dataSource" />
<property
name="channelMessageStoreQueryProvider"
ref="queryProvider" />
</bean>
<bean
id="queryProvider"
class="org.springframework.integration.jdbc.store.channel.H2ChannelMessageStoreQueryProvider" />
<!-- MQTT INBOUND ADAPTER IS CONFIGURED IN JAVA -->
<int-jpa:outbound-channel-adapter
channel="mqttInputChannel"
flush-size=""
entity-class="com.iot.db.DefaultBean"
persist-mode="PERSIST"
entity-manager-factory="entityManagerFactory">
<int-jpa:transactional transaction-manager="transactionManager" />
<int-jpa:request-handler-advice-chain>
<ref bean="retryAdvice" />
</int-jpa:request-handler-advice-chain>
</int-jpa:outbound-channel-adapter>
<int:handler-retry-advice id="retryAdvice" />
</beans>
有没有最佳实践或众所周知的模式如何处理这种情况?
提前致谢