Spring integration 分裂后平行富集
这是的延续,我们有一个外部API,允许从购物车结账。总而言之,我们有一个流程,在这个流程中,我们创建一个空购物,添加行项目,最后结帐。上面的所有操作都是通过对外部服务的HTTP调用来实现的。我们希望同时添加行项目(作为添加行项目调用的一部分)。我们当前的配置如下所示:Spring integration 分裂后平行富集,spring-integration,Spring Integration,这是的延续,我们有一个外部API,允许从购物车结账。总而言之,我们有一个流程,在这个流程中,我们创建一个空购物,添加行项目,最后结帐。上面的所有操作都是通过对外部服务的HTTP调用来实现的。我们希望同时添加行项目(作为添加行项目调用的一部分)。我们当前的配置如下所示: @Bean public IntegrationFlow fullCheckoutFlow() { return f -> f.channel("inputChannel") .transf
@Bean
public IntegrationFlow fullCheckoutFlow() {
return f -> f.channel("inputChannel")
.transform(fromJson(ShoppingCart.class))
.enrich(e -> e.requestChannel(SHOPPING_CART_CHANNEL))
.split(ShoppingCart.class, ShoppingCart::getLineItems)
.enrich(e -> e.requestChannel(ADD_LINE_ITEM_CHANNEL))
.aggregate(aggregator -> aggregator
.outputProcessor(g -> g.getMessages()
.stream()
.map(m -> (LineItem) m.getPayload())
.map(LineItem::getName)
.collect(joining(", "))))
.enrich(e -> e.requestChannel(CHECKOUT_CHANNEL))
.<String>handle((p, h) -> Message.called("We have " + p + " line items!!"));
}
@Bean
public IntegrationFlow addLineItem(Executor executor) {
return f -> f.channel(MessageChannels.executor(ADD_LINE_ITEM_CHANNEL, executor).get())
.handle(outboundGateway("http://localhost:8080/api/add-line-item", restTemplate())
.httpMethod(POST)
.expectedResponseType(String.class));
}
@Bean
public Executor executor(Tracer tracer, TraceKeys traceKeys, SpanNamer spanNamer) {
return new TraceableExecutorService(newFixedThreadPool(10), tracer, traceKeys, spanNamer);
}
@Bean
公共集成流FullCheckOutput(){
返回f->f.channel(“输入通道”)
.transform(fromJson(ShoppingCart.class))
.enrich(e->e.requestChannel(购物车通道))
.split(ShoppingCart.class,ShoppingCart::getLineItems)
.enrich(e->e.requestChannel(添加行项目通道))
.聚合(聚合器->聚合器
.outputProcessor(g->g.getMessages()
.stream()
.map(m->(LineItem)m.getPayload())
.map(LineItem::getName)
.collect(加入(“,”))
.enrich(e->e.requestChannel(签出通道))
.handle((p,h)->Message.called(“我们有“+p+”行项目!!”));
}
@豆子
公共集成流addLineItem(执行者执行者){
返回f->f.channel(MessageChannels.executor(ADD\u LINE\u ITEM\u channel,executor.get())
.handle(outboundGateway(“http://localhost:8080/api/add-行项目”,restTemplate())
.httpMethod(POST)
.expectedResponseType(String.class));
}
@豆子
公共遗嘱执行人遗嘱执行人(追踪器追踪器、追踪器追踪器、斯潘纳默斯潘纳默){
返回新的TraceableExecutorService(新的FixedThreadPool(10)、tracer、traceKeys、spanNamer);
}
为了并行添加行项目,我们使用一个executor通道。但是,当在zipkin中看到它们时,它们似乎仍在按顺序处理:
我们做错了什么?整个项目的来源是供参考的
谢谢 首先,Spring集成的主要功能是
MessageChannel
,但我仍然不清楚为什么人们在端点定义之间缺少.channel()
操作符
我的意思是,对于你的情况,它必须是这样的:
.split(ShoppingCart.class, ShoppingCart::getLineItems)
.channel(c -> c.executor(executor()))
.enrich(e -> e.requestChannel(ADD_LINE_ITEM_CHANNEL))
现在谈谈你的特殊问题
看,ContentEnricher
(.enrich()
)是请求-应答组件:
因此,它将请求发送到其requestChannel
,并等待回复。它独立于requestChannel
类型来完成
I raw Java我们可以用以下代码片段演示这种行为:
for (Object item: items) {
Data data = sendAndReceive(item);
}
您应该看到,ADD\u LINE\u ITEM\u CHANNEL
作为一个executor CHANNEL
没有太大价值,因为我们仍然被阻塞在回复的循环中
.split()
执行完全类似的循环,但由于默认情况下是使用DirectChannel
,因此在同一线程中进行迭代。因此,下一个项目等待上一个项目的答复
这就是为什么在
.split()
之后,您一定要将并行作为.rich()
的输入。所以,实际上我们正在做拆分器->执行器通道->充实。执行器通道是支持并行化的通道。我的理解正确吗?正确。enricher的requestChannel作为执行者之一是没有意义的,因为我们无论如何都会被阻止等待回复。