Spring Integration Aggregator和SimpleMessageGroup内存泄漏

时间:2018-06-01 18:25:30

标签: out-of-memory spring-integration

我们有一个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 }

我尝试过上述变量的不同设置和组合,但我仍然看到相同的行为。

SoapUI request details of SimpleMessageGroup Instance One SoapUI request details of SimpleMessageGroup Instance Two Screen shot of High Throughput run

非常感谢任何协助。

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。

2 个答案:

答案 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代替。