Spring boot Spring集成框架-动态注册流的缓慢性

Spring boot Spring集成框架-动态注册流的缓慢性,spring-boot,spring-integration,Spring Boot,Spring Integration,我们正在开发一个SpringBoot(2.4.0)应用程序,它使用SpringIntegrationFramework(5.4.1)构建SOAP集成流并动态注册它们。随着正在注册的流数量的增加,用“FlowContext”注册“IntegrationFlow”所需的时间呈指数增长。 以下是注册流所用时间的快速快照: 5个流量–500毫秒 100流量–80秒 300流量–300秒 我们看到,前几个流需要大约100ms才能注册,当它达到300时,注册每个流需要7秒。这些流本质上是相同的(它们只是记录

我们正在开发一个SpringBoot(2.4.0)应用程序,它使用SpringIntegrationFramework(5.4.1)构建SOAP集成流并动态注册它们。随着正在注册的流数量的增加,用“FlowContext”注册“IntegrationFlow”所需的时间呈指数增长。 以下是注册流所用时间的快速快照:

5个流量–500毫秒 100流量–80秒 300流量–300秒

我们看到,前几个流需要大约100ms才能注册,当它达到300时,注册每个流需要7秒。这些流本质上是相同的(它们只是记录一条信息消息并返回)

我们将非常感谢为解决这一问题提供的任何帮助

SoapFlowsAutoConfiguration.java(动态(手动)注册流的自动配置类)

SoapFlowResolver.java(所有集成流用于将请求委托给负责业务逻辑实现的Coreflow的公共类)

CoreFlow.java(处理业务逻辑的类)


你装了太多的豆子,每个豆子都会检查其余的豆子是否是以前创建的。这就是当动态添加越来越多的流时,随着开始时间的增加而增加的原因

我看到的是对动态流目的的滥用。每次我们决定这样做时,如果我们确实需要将整个流程作为一个新的实例,我们需要三思而后行。再说一次:流不是易失性对象,它在应用程序上下文中注册了一堆bean,这些bean将一直保留到您删除它们为止。它们是单例的,因此可以在应用程序的任何其他位置重用

Spring Integration
MessageChannel
模式实现的最佳特性中没有考虑到的另一个问题。您肯定可以提前拥有一些通用流,并通过它们之间的通道将动态连接到这些流。您可能只需要动态创建一个
SimpleWebServiceInboundGateway
,并将其与目标逻辑的通道连接起来,这对所有流都是一样的,以此类推

 @Bean
  public UriEndpointMapping uriEndpointMapping(
      ServerProperties serverProps,
      WebServicesProperties webServiceProps,
      IntegrationFlowContext flowContext,
      FlowMetadataProvider flowMetadataProvider,
      @ErrorChannel(Usage.SOAP) Optional<MessageChannel> errorChannel,
      BeanFactory beanFactory) {

    UriEndpointMapping uriEndpointMapping = new UriEndpointMapping();
    uriEndpointMapping.setUsePath(true);

    Map<String, Object> endpointMap = new HashMap<>();
    flowMetadataProvider
        .flowMetadatas()
        .forEach(
            metadata -> {
              String contextPath = serverProps.getServlet().getContextPath();
              String soapPath = webServiceProps.getPath();
              String serviceId = metadata.id();
              String serviceVersion = metadata.version();

              String basePath = contextPath + soapPath;

              String endpointPath = String.join("/", basePath, serviceId, serviceVersion);

              SimpleWebServiceInboundGateway inboundGateway = new SimpleWebServiceInboundGateway();
              errorChannel.ifPresent(inboundGateway::setErrorChannel);
              endpointMap.put(endpointPath, inboundGateway);
              IntegrationFlowFactory flowFactory = beanFactory.getBean(metadata.flowFactoryClass());

              IntegrationFlow integrationFlow =
                  IntegrationFlows.from(inboundGateway).gateway(flowFactory.createFlow()).get();
              flowContext.registration(integrationFlow).register();
            });
    uriEndpointMapping.setEndpointMap(endpointMap);
    return uriEndpointMapping;
  }
  @Autowired private SoapFlowResolver soapFlowResolver;
  @Autowired private CoreFlow delegate;

  @Override
  public IntegrationFlow createFlow() {
    IntegrationFlow a =
        flow -> flow.gateway(soapFlowResolver.resolveSoapFlow(delegate.createFlow()));
    return a;
  }
public IntegrationFlow resolveSoapFlow(
      IntegrationFlow coreFlow) {

    return flow -> {
      flow.gateway(coreFlow);
    };
  }
  @Override
  public IntegrationFlow createFlow() {

    return flow -> flow.logAndReply("Reached CoreFlow");
  }