如何使用Spring Integration MQTT入站适配器保证消息处理

时间:2017-04-18 15:39:36

标签: spring spring-integration

我们正在使用来自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>

有没有最佳实践或众所周知的模式如何处理这种情况?

提前致谢

0 个答案:

没有答案