Spring integration spring集成-拆分器和聚合器
目前,我正在为新应用程序与SpringIntegration合作,并启动了poc,以了解如何处理故障案例。 在我的应用程序中,spring integration将接收来自IBM mq的消息,并根据消息类型验证头信息和到不同队列的路由。传入的消息可能是批量消息,所以我使用了SpringIntegration中的拆分器和聚合器,并且在技术工作流程上取得了良好的进展和控制。 目前我面临的问题很少,我们有IBMMQ和webservice作为网关。两个网关都接收消息并发送到拆分器通道,其中拆分器拆分消息并发送到出站通道(执行器通道)。因此,消息将被并行发送到目的地,状态更新服务激活器将使用相同的通道以order=2接收消息并发送到聚合器。因此,为了它的良好实施 问题: 如果jms出站网关抛出我添加的advise as exception handler执行选项,它将发送到另一个service activator以将失败状态更新到DTO对象,并将具有与输出相同的聚合器通道,但在这种情况下,我不会在聚合器通道中接收消息,聚合器仅在愉快流中接收 我希望聚合出站成功消息和失败消息(其他服务激活器更新状态),然后需要将完整状态作为另一个出站或webservice中的响应发布到响应队列 我试图命令成功的ServiceActivator和失败错误处理程序ServiceActivator具有相同的通道,该通道是聚合器的输入通道,并且它不工作 感谢您的指导,继续执行此工作流程 使用Spring集成2.2.2Spring integration spring集成-拆分器和聚合器,spring-integration,Spring Integration,目前,我正在为新应用程序与SpringIntegration合作,并启动了poc,以了解如何处理故障案例。 在我的应用程序中,spring integration将接收来自IBM mq的消息,并根据消息类型验证头信息和到不同队列的路由。传入的消息可能是批量消息,所以我使用了SpringIntegration中的拆分器和聚合器,并且在技术工作流程上取得了良好的进展和控制。 目前我面临的问题很少,我们有IBMMQ和webservice作为网关。两个网关都接收消息并发送到拆分器通道,其中拆分器拆分消息
<channel id="inbound"/>
<channel id="splitterInChannel"/>
<channel id="splitterOutChannel">
<dispatcher task-executor="splitterExecutor"/>
</channel>
<beans:bean id="splitterExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<beans:property name="corePoolSize" value="5" />
<beans:property name="maxPoolSize" value="10" />
<beans:property name="queueCapacity" value="25" />
</beans:bean>
<channel id="ValidatorChannel"/>
<channel id="outBoundjmsChannel"/>
<channel id="outBoundErrorChannel"/>
<channel id="finalOutputChannel"></channel>
<channel id="aggregatorChannel"/>
<jms:inbound-channel-adapter connection-factory="AMQConnectionFactory"
destination="AMQueue" channel="inbound" auto-startup="true"
extract-payload="false" acknowledge="transacted"></jms:inbound-channel-adapter>
<service-activator ref="InBoundProcessor" input-channel="inbound" output-channel="splitterInChannel"></service-activator>
<!-- splitter -->
<splitter ref="Splitter" method="splitInput" input-channel="splitterInChannel" output-channel="splitterOutChannel"/>
<!-- validator -->
<service-activator ref="Validator" method="validate" input-channel="splitterOutChannel" output-channel="ValidatorChannel"/>
<!-- need to add enricher -->
<service-activator ref="Enricher" method="enrich" input-channel="ValidatorChannel" output-channel="outBoundjmsChannel"/>
<!-- outbound gateway -->
<jms:outbound-channel-adapter channel="outBoundjmsChannel" connection-factory="AMQConnectionFactory" destination-name="outputQueue"
message-converter="customMessageConvertor" order="1" >
<jms:request-handler-advice-chain>
<beans:bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<beans:property name="retryTemplate" >
<beans:bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<beans:property name="retryPolicy">
<beans:bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<beans:property name="maxAttempts" value="2" />
</beans:bean>
</beans:property>
<beans:property name="backOffPolicy">
<beans:bean class="org.springframework.retry.backoff.FixedBackOffPolicy">
<beans:property name="backOffPeriod" value="1000" />
</beans:bean>
</beans:property>
</beans:bean>
</beans:property>
<beans:property name="recoveryCallback">
<beans:bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
<beans:constructor-arg ref="outBoundErrorChannel" />
</beans:bean>
</beans:property>
</beans:bean>
</jms:request-handler-advice-chain>
</jms:outbound-channel-adapter>
<!-- outBound error processor -->
<service-activator ref="ErrorProcessor" method="errorHandling" input-channel="outBoundErrorChannel" output-channel="aggregatorChannel" />
<!-- Post send processor -->
<service-activator ref="PostProcessor" method="Postprocessing" input-channel="outBoundjmsChannel" output-channel="aggregatorChannel" order="2"/>
<!-- aggregator -->
<aggregator ref="Aggregator" correlation-strategy-method="aggregateStrategy" input-channel="aggregatorChannel" output-channel="finalOutputChannel"
release-strategy-method="isRelease" method="aggregate" expire-groups-upon-completion="true"/>
<!-- final processor or responder -->
<service-activator ref="FinalProcessor" method="endProcessing" input-channel="finalOutputChannel"/>
</beans:beans>
在上面的配置中,到目前为止,我已经将发布策略设置为false,将关联方法设置为空字符串。如果这样做有效,我将为批生成UUID,并将在拆分器中将UUID附加到Corrate
在调试上述配置时,我注意到出站错误通道receive每当试图发送到出站适配器时(在我的例子中,它发送两次)。我不想在一个应用程序中重新尝试,而在另一个应用程序中,它需要尝试重新发布消息。
在这两种情况下,我都希望在最终尝试聚合后将消息发送到出站错误通道,如果失败,我将在ErrorProcessor中将状态更新为failed to send
两个问题。
1.接收到重复的消息到通道,很难确定最后的失败或成功。
2.无法制定发布策略的逻辑,难以确定哪一个是重复的,以及是否成功
在上面的例子中,我找不到一种比较对象的通用方法,因为equals方法没有合适的属性进行比较,而且也不会
与布尔字段进行比较的正确方法
请帮助我解决此问题,以继续我的工作流设计和完成
非常感谢您指导我继续。
谢谢
克里斯S
目前
public Object errorHandling(Object object){
OutBoundMessage outBoundMessage = null;
if(object instanceof MessagingException){
outBoundMessage =((MessagingException) object).getFailedMessage();
}else{
//TODO: log the message
}
return outBoundMessage;
}
public String aggregateStrategy(OutBoundMessage outBoundMessage){
//TODO: get the UUID from outbound message and return
return "";
}
public List<OutBoundMessage> splitter(InBoundMessage inBoundMessage){
String[] message = inBoundMessage.getRawMessage().split(",");
long uuid = java.util.UUID.randomUUID().getLeastSignificantBits();
List<OutBoundMessage> outBoundMessagelist = new ArrayList<OutBoundMessage>();
for (String string : message) {
OutBoundMessage outBoundMessage = new outBoundMessage();
outBoundMessage.setCorrelationID(uuid);
outBoundMessagelist.add(outBoundMessage);
}
}
公共对象错误处理(对象){
OutBoundMessage OutBoundMessage=null;
if(MessaginException的对象实例){
outBoundMessage=((MessaginException)对象).getFailedMessage();
}否则{
//TODO:记录消息
}
返回外部消息;
}
公共字符串聚合策略(OutBoundMessage OutBoundMessage){
//TODO:从出站消息获取UUID并返回
返回“”;
}
公共列表拆分器(InBoundMessage InBoundMessage){
String[]message=inBoundMessage.getRawMessage().split(“,”);
long uuid=java.util.uuid.randomUUID().GetLeastSignificanBits();
List outBoundMessagelist=新建ArrayList();
for(字符串:消息){
OutBoundMessage OutBoundMessage=新的OutBoundMessage();
outBoundMessage.setCorrelationID(uuid);
outBoundMessagelist.add(outBoundMessage);
}
}
在以下方法中添加为默认值false以进行验证
public boolean isRelease(List<OutBoundMessage> outBoundMessage){
//TODO: need to define condition for closing the list aggregation
return false;
}
public boolean isRelease(列出outBoundMessage){
//TODO:需要定义关闭列表聚合的条件
返回false;
}
请分享您的ErrorProcessor
源代码。以及相关策略方法=“聚合策略”
我想知道您如何处理那里的ErrorMessage
,以及如何在ErrorProcessor
之后从消息中恢复correlationKey
不确定如何构建自己的correlationKey
,但默认情况下
提供applySequence=true
。因此,相关详细信息
在每个拆分的消息中都可用,以便能够在以后进行聚合
对于ErrorMessageSendingRecoverer
中的ErrorMessage
,我建议您注意那里的异常
负载
。它看起来像(从ErrorMessageSendingRecoverer
源代码):
else if(!(MessaginException的最后一个可丢弃实例)){
lastThrowable=new MessaginException((消息)context.getAttribute(“消息”),
lastThrowable.getMessage(
else if (!(lastThrowable instanceof MessagingException)) {
lastThrowable = new MessagingException((Message<?>) context.getAttribute("message"),
lastThrowable.getMessage(), lastThrowable);
}
....
messagingTemplate.send(new ErrorMessage(lastThrowable));