Spring integration Spring集成多线程

Spring integration Spring集成多线程,spring-integration,spring-jms,Spring Integration,Spring Jms,关于我之前在URL上的问题,我想我可能已经找到了问题的根源。 简单来说,我的要求是: 在1秒的固定延迟后轮询数据库,然后将非常有限的数据发布到Tibco EMS队列。现在,从这个EMS队列中,我必须以多线程方式完成以下任务:-我使用消息,我现在从数据库获取完整数据,我将数据转换为json格式 我的设计- 问题- 使用消息驱动通道,并发使用者值设置为5。然而,看起来只创建了一个消费者线程容器-2,并从EMS队列中提取消息。请在下面的log4j日志中查找- 2018年8月16日11:31:12077

关于我之前在URL上的问题,我想我可能已经找到了问题的根源。 简单来说,我的要求是: 在1秒的固定延迟后轮询数据库,然后将非常有限的数据发布到Tibco EMS队列。现在,从这个EMS队列中,我必须以多线程方式完成以下任务:-我使用消息,我现在从数据库获取完整数据,我将数据转换为json格式

我的设计-

问题- 使用消息驱动通道,并发使用者值设置为5。然而,看起来只创建了一个消费者线程容器-2,并从EMS队列中提取消息。请在下面的log4j日志中查找-

2018年8月16日11:31:12077信息SubscribeJMSMessageHandler[subscribechanneladapter.container-2][]:此时从队列读取的记录总数为387 记录1::[ID=7694066395]记录2:[ID=7694066423]。。记录387::[ID=6147457333]

可能的根本原因在这里- 这可能是配置中的第一步,在一个导致多线程问题的固定延迟之后,我轮询数据库以获取数据。参考上面的日志,我在这里的假设是,由于获取的记录数是387,并且所有这些记录都绑定到一个List object List>message中,因此只将其视为一条消息/负载,而不是387条不同的消息,这就是为什么只有一个线程/容器/消费者拾取此绑定消息的原因。这一假设的原因如下所示:

GenericMessage[payload=[{ID:7694066395},{ID:7694066423},{ID:6147457333}],headers={json_u内容类型ID_u=class org.springframework.util.LinkedCaseInsensitiveMap,jms_重新交付=false,json_u类型ID_uu=class java.util.ArrayList,jms_目的地=Queue[app.Queue.testQueue],id=e034ba73-7781-b62c-0307-170099263068,优先级=4,jms_时间戳=1534820792064,contentType=application/json,jms_messageId=id:test.21415B667C051:40C149C0,时间戳=1534820792481}]

问题- 我对根本原因的理解正确吗?如果是,那么如何将这387条消息视为单独的消息,而不是消息的一个列表对象,并在不影响事务管理的情况下逐个发布它们??
在我之前关于stackoverflow的文章中,我已经讨论了这个问题,我必须用ActiveMQ替换Tibco EMS来检查这个设计。然而,我们的架构团队仍在分析ActiveMQ基础架构,因此在其获得批准之前无法使用

哦!现在我知道你有什么问题了。intjdbc:inbound通道适配器确实返回了它可以从数据库中选择的记录列表。整个列表作为一条消息发送给JMS。这就是为什么在消费者端只能看到一个线程的原因:只有一条消息可以从队列中获取


如果您想对每个被拉出的记录有单独的消息,则需要考虑使用JDBC轮询操作并发送到JMS。< /P>如果在JDBC轮询操作和发送到EMS队列中使用它,希望使用不会中断事务。在我的设计中,我设置事务的方式类似于:当第一次数据库轮询获取10条记录时,事务开始,当这些记录被发送到Tibco EMS队列时,事务结束。只有在它被发送到EMS队列之后,第二次轮询才应该开始,并随之进行第二次事务处理。请确认这是正确的,只要下游的一切都在我为每个拉取记录使用的相同轮询线程中执行,那么每个轮询都有事务,并且整个子流都有事务。我现在可以看到多个线程。谢谢这里有一个问题-我使用log4j框架记录消息-是否有任何方法将我设计中使用的每个消息通道的“id”记录在日志文件中?让我们将其作为一个单独的SO问题来安排!我已将此作为一个单独的SO问题进行了安排-

`<int:channel id="dbchannel"/>   
    <int-jdbc:inbound-channel-adapter id="dbchanneladapter"  
        channel="dbchannel"  data-source="datasource"  
        query="${selectquery}"  update="${updatequery}"  
        max-rows-per-poll="1000">  
        <int:poller id="dbchanneladapterpoller"  
            fixed-delay="1000">  
            <int:transactional transaction-manager="transactionmanager" />  
        </int:poller>  
    </int-jdbc:inbound-channel-adapter>  
    <int:service-activator input-channel="dbchannel"
        output-channel="publishchannel" ref="jdbcmessagehandler" method="handleJdbcMessage" />  
    <bean id="jdbcmessagehandler" class="com.citigroup.handler.JdbcMessageHandler" />  

    <int:publish-subscribe-channel id="publishchannel"/>  
    <int-jms:outbound-channel-adapter id="publishchanneladapter"
        channel="publishchannel" jms-template="publishrealtimefeedinternaljmstemplate" />  

    <int:channel id="subscribechannel"/>  
    <int-jms:message-driven-channel-adapter
        id="subscribechanneladapter" destination="subscriberealtimeinternalqueue" 
        connection-factory="authenticationconnectionfactory" channel="subscribechannel" 
        concurrent-consumers="5" max-concurrent-consumers="5" />  
    <int:service-activator input-channel="subscribechannel"
        ref="subscribemessagehandler" method="logJMSMessage" />  
    <bean id="subscribemessagehandler" class="com.citigroup.handler.SubscribeJMSMessageHandler" />  
</beans>  

<bean id="authenticationconnectionfactory"
        class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
        <property name="targetConnectionFactory" ref="connectionFactory" />
        <property name="username" value="test" />
        <property name="password" value="test123" />
    </bean>  

<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName" value="app.jndi.testCF" />
</bean>  

<bean id="subscriberealtimeinternalqueue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName"
        value="app.queue.testQueue" />
</bean>   
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory
            </prop>
            <prop key="java.naming.provider.url">tibjmsnaming://test01d.nam.nsroot.net:7222</prop>
        </props>
    </property>
</bean>`