简体   繁体   English

Spring Integration Java DSL-异步执行多个服务激活器?

[英]Spring Integration Java DSL - execute multiple service activators async?

There's a Job which has a list of tasks. 有一个作业,其中包含任务列表。 Each task has id, name, status. 每个任务都有ID,名称,状态。

I've created service activators for each tasks, as follows: 我为每个任务创建了服务激活器,如下所示:

@ServiceActivator
public Message<Task> execute(Message<Task> message){
    //do stuff
}

I've created a gateway for Job and in the Integration flow, starting from the gateway: 我已经从网关开始为Job创建了一个网关,并在Integration流中创建了一个网关:

@Bean
    public IntegrationFlow startJob() {
        return f -> f
                .handle("jobService", "execute")
                .channel("TaskRoutingChannel");
    }

@Bean
    public IntegrationFlow startJobTask() {
        return IntegrationFlows.from("TaskRoutingChannel")
                .handle("jobService", "executeTasks")
                .route("headers['Destination-Channel']")
                .get();
    }

@Bean
    public IntegrationFlow TaskFlow() {
        return IntegrationFlows.from("testTaskChannel")
                .handle("aTaskService", "execute")
                .channel("TaskRoutingChannel")
                .get();
    }

@Bean
    public IntegrationFlow TaskFlow2() {
        return IntegrationFlows.from("test2TaskChannel")
                .handle("bTaskService", "execute")
                .channel("TaskRoutingChannel")
                .get();
    }

I've got the tasks to execute sequentially, using routers as above. 我已经使用上述路由器按顺序执行任务。

However, I need to start the job, execute all of it's tasks in parallel. 但是,我需要开始工作,并行执行所有任务。 I couldn't figure out how to get that going.. I tried using @Async on the service activator methods and making it return void . 我不知道该怎么@Async 。我尝试在服务激活器方法上使用@Async并使它返回void but in that case, how do i chain it back to the routing channel and make it start next task? 但是在那种情况下,我如何将其链接回路由通道并使其开始下一个任务? Please help. 请帮忙。 Thanks. 谢谢。

EDIT : 编辑

I used the RecepientListRouter along with ExecutorChannel to get the parallel execution: 我将RecepientListRouter和ExecutorChannel一起使用来执行并行执行:

@Bean
public IntegrationFlow startJobTask() {
    return IntegrationFlows.from("TaskRoutingChannel")
            .handle("jobService", "executeTasks")
            .routeToRecipients(r -> r
                .recipient("testTaskChannel")
                .recipient("test2TaskChannel"))
            .get();
}

@Bean ExecutorChannel testTaskChannel(){
    return new ExecutorChannel(this.getAsyncExecutor());
}

@Bean ExecutorChannel test2TaskChannel(){
    return new ExecutorChannel(this.getAsyncExecutor());
}
@Bean
public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setMaxPoolSize(10);
    executor.setQueueCapacity(10);
    executor.initialize();
    return executor;
}

Now, 3 questions: 1) If this is a good approach, how do i send specific parts of the payload to each recipient channel. 现在,有3个问题:1)如果这是一个好方法,我如何将有效负载的特定部分发送到每个接收者通道。 Assume the payload is a List<>, and i want to send each list item to each channel. 假设有效载荷是一个List <>,我想将每个列表项发送到每个通道。 2) How do I dynamically set the recipient channel? 2)如何动态设置收件人频道? say from header? 从标题说? or a list? 或清单? 3) Is this really a good approach? 3)这真的是一个好方法吗? Is there a preferred way to do this? 有没有首选的方法可以做到这一点?

Thanks in Advance. 提前致谢。

Your TaskRoutingChannel must be an instance of ExecutorChannel . 您的TaskRoutingChannel必须是ExecutorChannel的实例。 For example: 例如:

return f -> f
            .handle("jobService", "execute")
            .channel(c -> c.executor("TaskRoutingChannel", threadPoolTaskExecutor()));

Otherwise, yes: everything is invoked with the single Thread and it isn't good for your task. 否则,是的:所有事情都由单个Thread调用,这对您的任务不利。

UPDATE UPDATE

Let me try to answer to your questions one by one, although it sounds like each of them must as separate SO one :-). 让我尝试一个接一个地回答您的问题,尽管听起来每个问题都必须单独列出一个:-)。

  1. If you really need to send the same message to several services, you can use routeToRecipients , or can back to the publishSubscribe . 如果确实需要将同一条消息发送到多个服务,则可以使用routeToRecipients ,也可以返回到publishSubscribe Or even can do dynamic routing based on the header , for example. 甚至可以基于header执行动态路由。

  2. To send the part of message to each channel there is just enough place .split() before your .routeToRecipients() 要将消息的一部分发送到每个通道,请在.routeToRecipients()之前放置足够的.split()位置

  3. To answer to your last question I need to know the business requirements for the task. 要回答您的最后一个问题,我需要了解任务的业务需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM