这是我的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>
答案 0 :(得分:1)
为什么这么多队列频道?你只需要一个切换点到多线程;尝试在jdbc适配器轮询器的线程上调用拆分器。
编辑:
你想通过几乎每个频道QueueChannel
来实现什么?这导致了大量的线程上下文切换。
我建议首先使用除DirectChannel
之外的所有通道splitQueueChannel
,然后在您发现需要时向下游添加更多并发。但是几乎每个频道的队列频道都是过多的,除非你想要实现的某些特定内容我没有看到。