Spring-Integration:在Spl for Splitter和Routers中配置TaskExecutor以增加并发处理

时间:2014-04-10 21:21:04

标签: spring spring-integration

enter image description here这是我的Spring-Integration-config:

jdbc-inbound-adapter --> 1st QueueChannel --> Splitter --> Router --> ServiceActivator -->outbound-channel-adapter

当我执行一个6000个消息的加载,这些消息在一个表中被jdbc-inbound-adapter选中时需要34分钟来处理所有这些消息。

我发现需要花费大量时间才能从Splitter转移到Router。为了减少时间,我可以使用以下配置:(请参阅轮询器固定延迟和接收超时

<si:splitter input-channel="firstQueueChannel" output-channel="splitQueueChannel" auto-startup="true" send-timeout="1">
    <si:poller fixed-delay="50" time-unit="MILLISECONDS" receive-timeout="5000" max-messages-per-poll="200" task-executor="messageTypeSplitterTaskExecutor"/>
</si:splitter>

<task:executor id="messageTypeSplitterTaskExecutor" pool-size="2-20" queue-capacity="10" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<si:router input-channel="splitQueueChannel" ref="messageTypeRouter" method ="routeMessage" auto-startup="true" >
    <si:poller fixed-delay="50" time-unit="MILLISECONDS" receive-timeout="5000" max-messages-per-poll="200" task-executor="messageTypeRouterTaskExecutor"/>     
</si:router>

<task:executor id="messageTypeRouterTaskExecutor" pool-size="2-20" queue-capacity="10" keep-alive="1" rejection-policy="CALLER_RUNS"/>

我的问题是:我应该在Poller上使用固定速率还是固定延迟,如果Gary在此链接中建议接收超时应为0: Spring integration - Queue/Poller seems to exhaust threadpool without any action

如果有人可以指出我正确的方向,那就太好了。我们在30%负载下获得400K消息负载

更新: 这是jdbc-inbound-adapter配置,适配器使用把消息放在'firstQueueChannel'上:

 <si-jdbc:inbound-channel-adapter id="jdbcInboundAdapter"
    channel="firstQueueChannel" data-source="myDataSource"
    auto-startup="true"
    query="SELECT * FROM STAGE_TABLE WHERE STATUS='WAITING'  FOR UPDATE SKIP LOCKED"
    update="UPDATE STAGE_TABLE SET STATUS='IN_PROGRESS' WHERE ID IN (:Id)"
    max-rows-per-poll="100" row-mapper="rowMapper"
    update-per-row="true">

    <si:poller fixed-rate="5000">
        <si:advice-chain> 
            <ref bean="txAdvice"/> 
            <ref bean="inboundAdapterConfiguration"/> 
        </si:advice-chain>
    </si:poller>
</si-jdbc:inbound-channel-adapter>

UPDATE2: 这是具有所有细节的高级别:

  JdbcInboundAdapter  --> Splitter ---> Router ---> Service-Activators---> Router (Routed by Result Category) ---> Service Activators --> Router (Routed by Result Type) ---> Service Activators ---> Aggregator  --> Outboundchannel adapter

以下是完整配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:si="http://www.springframework.org/schema/integration"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:si-jdbc="http://www.springframework.org/schema/integration/jdbc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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-2.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc-2.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!--This channel is linked to the inbound-adapter --> 
<si:channel id="firstQueueChannel">
    <si:queue capacity="200"/>
</si:channel>

<bean id="mapperUtil" class="com.foo.service.process.mapper.common.MapperUtil"></bean>

<bean id="rowMapperForHighPriority" class="com.foo.service.process.mapper.HighPriorityResultStatusMapper"></bean>

<bean id="inboundAdapterPollingConfiguration" class="com.foo.service.download.retriever.impl.InboundAdapterPollingConfigurationImpl">
    <property name="channel" ref="firstQueueChannel"/>
    <property name="jdbcInboundAdapter" ref="jdbcInboundAdapter"/>      
</bean>


 <!--#################1. JDBC-INBOUND-ADAPTER: This pushes messages to the channel ###########################--> 
<si-jdbc:inbound-channel-adapter id="jdbcInboundAdapter"
    channel="firstQueueChannel" data-source="myDataSource"
    auto-startup="true"
    query="SELECT * FROM STAGE_TABLE WHERE STATUS='WAITING'  FOR UPDATE SKIP LOCKED"
    update="UPDATE STAGE_TABLE SET STATUS='IN_PROGRESS' WHERE ID IN (:Id)"
    max-rows-per-poll="100" row-mapper="rowMapper"
    update-per-row="true">

    <si:poller fixed-rate="5000">
        <si:advice-chain> 
            <ref bean="txAdvice"/> 
            <ref bean="inboundAdapterConfiguration"/> 
        </si:advice-chain>
    </si:poller>
</si-jdbc:inbound-channel-adapter>

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="get*" read-only="false"/>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!--#################2. This splits the Payload of List to individual payload ################################--> 
<si:splitter input-channel="firstQueueChannel" output-channel="splitQueueChannel" auto-startup="true" send-timeout="1">
    <si:poller fixed-delay="50" time-unit="MILLISECONDS" receive-timeout="5000" max-messages-per-poll="200" task-executor="messageTypeSplitterTaskExecutor"/>
</si:splitter>

<si:channel id="splitQueueChannel">
    <si:queue capacity="200"/>
</si:channel>

<task:executor id="messageTypeSplitterTaskExecutor" pool-size="2-20" queue-capacity="10" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!--##################################### 3. Here we get 2 types of messages STATUS, RESULT and RESULT_SET this ROUTER would route messages depending on the message type  #####################################-->  
<si:router input-channel="splitQueueChannel" ref="messageTypeRouter" method ="routeMessage" auto-startup="true" >
    <si:poller fixed-delay="50" time-unit="MILLISECONDS" receive-timeout="5000" max-messages-per-poll="200" task-executor="messageTypeRouterTaskExecutor"/>     
</si:router>

<bean id="messageTypeHighRouter" class="com.foo.service.process.router.MessageTypeHighRouter"/>

<task:executor id="messageTypeRouterTaskExecutor" pool-size="2-20" queue-capacity="10" keep-alive="1" rejection-policy="CALLER_RUNS"/>


<!-- STATUS MESSAGES GO TO THIS CHANNEL --> 
<si:channel id="statusHighChannel">
    <si:queue capacity="50"/>
 </si:channel>

<!--#####################################4.  SERVICE ACTIVATOR TO PROCESS THE STATUS-MESSAGES #####################################-->
<si:service-activator input-channel="statusHighChannel" ref="statusConsumeService" method="consumeStatus" output-channel="ackHighChannel">
    <si:poller task-executor="statusMessageHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>
<task:executor id="statusMessageHighTaskExecutor" pool-size="2-15" queue-capacity="5" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- ACKNOWLEDGE CHANNEL -->
<si:channel id="ackHighChannel"/>


<!--#####################################5.  Processing Results  #####################################-->
<!-- Have a Router to Route results according to OrderType on OrderTypeHandler Channels 
     and on each channel have a service activator to process the results accordingly   -->

<!-- BELOW ARE THE CHANNEL DEFINITIONS FOR RESULT AND RESULT_SET -->
<si:channel id="highSimpleOrderResultChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:channel id="resultHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:channel id="resultOrderSetHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:channel id="resultOrderSetSplitHighChannel">
    <si:queue capacity="50"/>
</si:channel>   

<!--##################################### 6. This service-activator would get a RESULT_SET Object which would convert it to List<RESULT> and returns it #####################################-->
<si:service-activator input-channel="resultOrderSetHighChannel"
    output-channel="resultOrderSetSplitHighChannel" ref="resultOrderSetSplitter"
    method="splitOrderSetResultToOrderResult">
    <si:poller task-executor="resultMessageSetHighTaskExecutor"
        fixed-delay="1000" />
</si:service-activator> 

<task:executor id="resultMessageSetHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!--##################################### 7. This bean converts RESULT Object to List<RESULT> object and the list size is 1 #####################################-->
<bean id="simpleOrderResultMapper" class="com.foo.service.process.transformer.SimpleMissionResultTransformer"/>

<si:transformer id="simpleOrderResultHighTransformer" input-channel="highSimpleOrderResultChannel" method="transform" output-channel="resultOrderSetSplitHighChannel" ref="simpleOrderResultMapper"/>


<bean id="splitterBean" class="com.foo.service.process.impl.MessageSplitter" />

<!--#####################################8. SPLITTER : LIST<RESULT> to RESULT #####################################-->
<si:chain input-channel="resultOrderSetSplitHighChannel" output-channel="resultHighChannel">
    <si:splitter ref="splitterBean"/> 
</si:chain>


<!--##################################### 9. This service would update the OrderTypeCategory attribute in the payload #####################################-->
<si:service-activator input-channel="resultHighChannel"
    output-channel="processResultHighChannel" ref="resultAssignCategoryService"
    method="processCategoryResults">
    <si:poller task-executor="resultMessageHighTaskExecutor"
        fixed-delay="1000" />
</si:service-activator> 
<task:executor id="resultMessageHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!--#####################################10. This router uses the OrderTypeCategory attribute to route to the below channels #####################################-->
<si:router input-channel="processResultHighChannel"  ref="orderTypeCategoryRouter" method ="routeHighMessage"/> 

<!-- ORDER-TYPE-CATEGORY Channels -->
<si:channel id="ORDERHighChannel">
    <si:queue capacity="50"/>
</si:channel>
<si:channel id="NOTIFICATION_SOFTWARE_UPDATEHighChannel">
    <si:queue capacity="50"/>
</si:channel>
<si:channel id="NOTIFICATION_USERHighChannel">
    <si:queue capacity="50"/>
</si:channel>
<si:channel id="ALERTHighChannel">
    <si:queue capacity="50"/>
</si:channel>
<si:channel id="FILE_WATCHERHighChannel">
    <si:queue capacity="50"/>
</si:channel>
<si:channel id="ERRORHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:transformer id="highTransformer" input-channel="ERRORHighChannel" method="transform" output-channel="ackHighChannel" ref="OrderResultsMessageTransformer"/>

<!--11. This service-activator would update the OrderType attribute in the payload-->
<si:service-activator input-channel="ORDERHighChannel" output-channel="processORDERHighChannel" ref="resultAssignCategoryService" method="processOrderResults" >
    <si:poller task-executor="resultOrderHighTaskExecutor" fixed-delay="1000" />        
</si:service-activator>

<task:executor id="resultOrderHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!--#######12. This router would use the OrderType Attribute to route to different channels and the service-activators on the channels will process the messages#####-->
<si:router input-channel="processORDERHighChannel" ref ="orderTypeRouter" method ="routeHighMessage"/>

<!--############13. Below are the list of channels and service-activators which process the messages when they reach their respective channels###############-->

    <!-- Get_Properties Handler   -->
<si:channel id="GET_PROPERTIESHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="GET_PROPERTIESHighChannel" ref="getPropertiesHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="getPropertiesHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="getPropertiesHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>


<!-- Set_Properties Handler   -->
<si:channel id="SET_PROPERTIESHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="SET_PROPERTIESHighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="setPropertiesHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="setPropertiesHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- ADD_PROPERTIES Handler   --> 
<si:channel id="ADD_AGENT_PROPERTIESHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="ADD_AGENT_PROPERTIESHighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="addAgentPropertiesHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="addAgentPropertiesHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- FILE_DOWNLOAD_ Handler   -->    
<si:channel id="FILE_DOWNLOAD_HighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="FILE_DOWNLOAD_HighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="fileDownloadHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="fileDownloadHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- GROOVY_SCRIPT_EXECUTION Handler   -->  
<si:channel id="GROOVY_SCRIPT_EXECUTIONHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="GROOVY_SCRIPT_EXECUTIONHighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="groovyScriptExecutionHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="groovyScriptExecutionHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- SHELL_SCRIPT_EXECUTION Handler   -->   
<si:channel id="SHELL_SCRIPT_EXECUTIONHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="SHELL_SCRIPT_EXECUTIONHighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="shellScriptExecutionHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="shellScriptExecutionHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- NOTIFY_DEVICE Handler   -->    
<si:channel id="NOTIFY_DEVICEHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="NOTIFY_DEVICEHighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="notifyDeviceHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="notifyDeviceHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- AGENT_REGISTRATION Handler   -->   
<si:channel id="AGENT_REGISTRATIONHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="REGISTRATIONHighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="registrationHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="registrationHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- FILE_WATCHER Handler   --> 
<si:channel id="FILE_WATCHERHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="FILE_WATCHERHighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="fileWatcherHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="fileWatcherHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- CONFIGURE_FAST_POLLING Handler   -->   
<si:channel id="CONFIGURE_POLLINGHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="CONFIGURE_POLLINGHighChannel" ref="updateResultStatusHandler" method="handleRawMissionResult" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="configurePollingHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="configurePollingHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- FILE_UPLOAD_TO_ENTERPRISE Handler, This is Murthy's Service   -->
<si:channel id="FILE_UPLOAD_HighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="FILE_UPLOAD_HighChannel" expression="@fileTransferHandler.handleMissionResult(payload,false,headers)" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="fileUploadToEnterpriseHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="fileUploadHandlerHighTaskExecutor" pool-size="10-30" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>


<!-- DB_SCRIPT_EXECUTION Handler   -->  
<si:channel id="DB_SCRIPT_EXECUTIONHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="DB_SCRIPT_EXECUTIONHighChannel" expression="@fileTransferHandler.handleMissionResult(payload,false,headers)" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="dbScriptExecutionHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="dbScriptExecutionHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- FILE_SEARCH Handler   -->  
<si:channel id="FILE_SEARCHHighChannel">
    <si:queue capacity="50"/>
</si:channel>

<si:service-activator input-channel="FILE_SEARCHHighChannel" expression="@fileSearchHandler.handleMissionResult(payload,headers)" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="fileSearchHandlerHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="fileSearchHandlerHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/> 

<!--Category Handlers   -->

<!-- DIRECTORY_WATCHER Handler   -->
<si:channel id="FILE_WATCHER_CATEGORYHighChannel">
    <si:queue capacity="50"/>
</si:channel> 

<si:service-activator input-channel="FILE_WATCHER_CATEGORYHighChannel" expression="@fileTransferHandler.handleMissionResult(payload,true,headers)" output-channel="prepareResultsHighChannel">
    <si:poller task-executor="fileWatcherHandlerCategoryHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<task:executor id="fileWatcherHandlerCategoryHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- Below are the channels required to do aggregation -->
<si:channel id="prepareResultsHighChannel">
    <si:queue capacity="500"/>
</si:channel>
<si:channel id="aggregateHighChannel">
    <si:queue capacity="500"/>
</si:channel>
<si:channel id="aggregateFileSearchHighChannel">
    <si:queue capacity="500"/>
</si:channel>
<si:channel id="aggregateCommonHighChannel">
    <si:queue capacity="500"/>
</si:channel>
<si:channel id="discardHighChannel">
    <si:queue capacity="500"/>
</si:channel>

<!--######################################14.AGGREGATOR for the Result Messages######################################################################-->  
<bean id="resultAggregatorBean" class="com.foo.service.consume.result.ResultAggregator" />

<si:aggregator input-channel="prepareResultsHighChannel" output-channel="aggregateHighChannel"
ref="resultAggregatorBean" method="send" release-strategy="resultAggregatorBean"
release-strategy-method="release" correlation-strategy="resultAggregatorBean"
correlation-strategy-method="correlate" send-partial-result-on-expiry="false" send-timeout="300000" discard-channel="discardHighChannel"/>

<!--#####################################15 ROUTER - To send to different activators depending on the type of result#############################################################################-->
<bean id="aggregatorRouter" class="com.foo.service.process.router.AggregatorRouter"/>   
<si:router input-channel="aggregateHighChannel"  ref="aggregatorRouter" method ="routeHighMessage"/>     

<bean id="aggregatorUtil" class="com.foo.model.process.aggregate.AggregatorUtil"/>

<bean id="aggregateFileSearchResultService" class="com.foo.model.process.aggregate.impl.AggregateFileSearchResultServiceImpl">
    <property name="missionResultDAO" ref="missionResultDAO"/>
    <property name="aggregatorUtil" ref="aggregatorUtil"/>
</bean> 

<!-- SERVICE-ACTIVATOR TO PROCESS MESSAGE ON HIGH PRIORITY, DEFAULT OR ADVANCE FILE-SEARCH-CHANNEL   -->
<si:service-activator input-channel="aggregateFileSearchHighChannel"  ref="aggregateFileSearchResultService" method="processAggregatorResponse" output-channel="ackHighChannel">
    <si:poller task-executor="aggregateResultHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<!-- TASK EXECUTOR TO PROCESS MESSAGE ON ON HIGH PRIORITY FILE-SEARCH-CHANNEL   -->
<task:executor id="aggregateResultHighTaskExecutor" pool-size="2-15" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!-- BEAN TO PROCESS MESSAGE ON COMMON-CHANNEL   -->
<bean id="aggregateCommonResultService" class="com.foo.model.process.aggregate.impl.AggregateCommonResultServiceImpl">
    <property name="missionResultDAO" ref="missionResultDAO"/>
    <property name="aggregatorUtil" ref="aggregatorUtil"/>
</bean> 

<!-- SERVICE-ACTIVATOR TO PROCESS MESSAGE ON COMMON-CHANNEL   -->
<si:service-activator input-channel="aggregateCommonHighChannel"  ref="aggregateCommonResultService" method="processAggregatorResponse" output-channel="ackHighChannel">
    <si:poller task-executor="aggregateCommonHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>

<!-- TASK EXECUTOR TO PROCESS MESSAGE ON COMMON-CHANNEL   -->
<task:executor id="aggregateCommonHighTaskExecutor" pool-size="2-30" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>


<bean id="evaluateResultService" class="com.foo.model.process.aggregate.impl.EvaluateResultServiceImpl">
    <property name="missionResultDAO" ref="missionResultDAO"/>
</bean>

<bean id="discardResultDAO" class="com.foo.dao.mission.result.impl.DiscardResultDAOImpl">
    <property name="sessionFactory" ref="mySessionFactory" />
    <property name="missionResultDAO" ref="missionResultDAO"/>
</bean>

<!-- BEAN TO PROCESS MESSAGE ON DISCARD-CHANNEL   -->
<bean id="discardResultService" class="com.foo.model.process.aggregate.impl.DiscardResultServiceImpl">
    <property name="discardResultDAO" ref="discardResultDAO"/>
    <property name="aggregatorUtil" ref="aggregatorUtil"/>
</bean>     

<!-- SERVICE-ACTIVATOR TO PROCESS MESSAGE ON DISCARD-CHANNEL   -->
<si:service-activator input-channel="discardHighChannel"  ref="discardResultService" method="applyFailureStatusToMessagesOnDiscardChannel" output-channel="ackHighChannel">
    <si:poller task-executor="discardHighTaskExecutor" fixed-delay="1000"/>
</si:service-activator>     

<!-- TASK EXECUTOR TO PROCESS MESSAGE ON DISCARD-CHANNEL   -->
<task:executor id="discardHighTaskExecutor" pool-size="2-30" queue-capacity="2" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<!--###################################16.  dispatch the result###########################################################-->
<!-- THIS IS THE FINAL ELEMENT WHICH WOULD UPDATE THE STAGING TABLE WITH THE MESSAGE STATUS TO SUCESS OR FAILURE -->
<si:outbound-channel-adapter ref="acknowledgementService" method="receiveMessage" channel="ackHighChannel" order="1">       
</si:outbound-channel-adapter>

</beans>

1 个答案:

答案 0 :(得分:1)

为什么这么多队列频道?你只需要一个切换点到多线程;尝试在jdbc适配器轮询器的线程上调用拆分器。

编辑:

你想通过几乎每个频道QueueChannel来实现什么?这导致了大量的线程上下文切换。

我建议首先使用除DirectChannel之外的所有通道splitQueueChannel,然后在您发现需要时向下游添加更多并发。但是几乎每个频道的队列频道都是过多的,除非你想要实现的某些特定内容我没有看到。