我们有一个Spring Integration应用程序,并且在高吞吐量(生产批处理过程)期间出现内存错误。该应用程序正在使用Spring-integration-core发行版4.3.10。我们在我们的应用程序和我们的Aggregator对象(@ MessageEndpoint / @ Autowired / @ Aggregator)上使用org.springframework.integration.annotation *并使用自定义的'聚合'方法。
在堆转储中,我看到来自高吞吐量运行的SimpleMessageGroup(以及其他关联对象),以及运行单个SoapUI请求时。请参阅随附的屏幕截图。
我已经读过可以在'AggregatingMessageHandler'对象中设置的许多变量。为了获得对这些变量的访问权限,同时仍然使用'spring.integration.annotation'并使用自定义'聚合'方法',我更改了带注释的聚合器对象扩展'AggregatingMessageHandler'。
@MessageEndpoint
public class MyAggregator extends AggregatingMessageHandler {
private final MyLogger myTransactionLogger;
@Autowired
public CIPAggregator( MyLogger myTransactionLogger) {
super(new DefaultAggregatingMessageGroupProcessor(), new SimpleMessageStore());
this.setSendPartialResultOnExpiry(false);
this.setExpireGroupsUponCompletion(true);
//this.setMinimumTimeoutForEmptyGroups(500);
this.setGroupTimeoutExpression(new ValueExpression<>(1000L));
this.setExpireGroupsUponTimeout(true);
this.cipTransactionLogger = cipTransactionLogger;
}
@Aggregator(inputChannel = "serviceResponseChannel", outputChannel="aggregatorResponseChannel")
public <T> IndividualInquiryResponse aggregate(List<Message> serviceResponses) {...custom code }
我尝试过上述变量的不同设置和组合,但我仍然看到相同的行为。
非常感谢任何协助。
2018年6月6日更新 根据Artem Bilan的说明 通过使用带有AggregatorFactoryBean的@Bean \ @ServiceActivator批注成功配置了Aggregator。 (MyAggregator对象不包含任何注释)
@Bean
@ServiceActivator(inputChannel = "serviceResponseChannel")
FactoryBean<MessageHandler> aggregatorFactoryBean( ) {
AggregatorFactoryBean aggregatorFactoryBean = new AggregatorFactoryBean();
aggregatorFactoryBean.setProcessorBean(new MyAggregator(myTransactionLogger()));
aggregatorFactoryBean.setMethodName("aggregate");
aggregatorFactoryBean.setMessageStore(new SimpleMessageStore());
aggregatorFactoryBean.setOutputChannel(aggregatorResponseChannel());
aggregatorFactoryBean.setExpireGroupsUponTimeout(true);
aggregatorFactoryBean.setGroupTimeoutExpression(new ValueExpression<>(1900L));// @MessagingGateway defaultReplyTimeout=2000
aggregatorFactoryBean.setSendPartialResultOnExpiry(false);
aggregatorFactoryBean.setExpireGroupsUponCompletion(true);
return aggregatorFactoryBean;
}
按预期接收响应,但仍存在SimpleMessageGroup和关联对象的内存泄漏问题。每个请求一个SimpleMessageGroup。
答案 0 :(得分:1)
If you are using a custom aggregate method within an Aggregator object, define an AggregatorFactoryBean similar to the following. Your Aggregator object should not contain an annotations
@Bean
@ServiceActivator(inputChannel = "serviceResponseChannel")
FactoryBean<MessageHandler> aggregatorFactoryBean( ) {
AggregatorFactoryBean aggregatorFactoryBean = new AggregatorFactoryBean();
aggregatorFactoryBean.setProcessorBean(new MyAggregator(myTransactionLogger()));//your Aggregator object
aggregatorFactoryBean.setMethodName("aggregate");//your aggregator method
aggregatorFactoryBean.setMessageStore(new SimpleMessageStore());
aggregatorFactoryBean.setOutputChannel(aggregatorResponseChannel());
aggregatorFactoryBean.setSendPartialResultOnExpiry(false);
aggregatorFactoryBean.setExpireGroupsUponCompletion(true);
aggregatorFactoryBean.setExpireGroupsUponTimeout(true);
aggregatorFactoryBean.setGroupTimeoutExpression(new ValueExpression<>(1900L));// @MessagingGateway defaultReplyTimeout=2000
return aggregatorFactoryBean;
}
public class MyAggregator {
private final MyLogger myTransactionLogger;
public MyAggregator( MyLogger myTransactionLogger) {
this.myTransactionLogger = myTransactionLogger;
}
public <T> InquiryResponse aggregate(List<Message> serviceResponses) {
your aggregatation code.....
}
}
答案 1 :(得分:0)
请与我们分享您的用例的ReleaseStrategy
。
默认情况下,聚合器会尝试按correlationId
标头对邮件进行分组。
并决定何时何时通过sequenceSize
标题发布组。如果不满足此条件,则组不会被释放并保留在内存中。
考虑在@ServiceActivator
AggregatorFactoryBean
上使用@Bean
代替。