我想更改单个订户的代码。现在我有
auctionFlux.window(Duration.ofSeconds(120), Duration.ofSeconds(120)).subscribe(
s -> s.groupBy(Auction::getItem).subscribe( longAuctionGroupedFlux -> longAuctionGroupedFlux.reduce(new ItemDumpStats(), this::calculateStats )
));
此代码正常工作,reduce方法非常简单。我尝试更改单个订户的代码
auctionFlux.window(Duration.ofSeconds(120), Duration.ofSeconds(120))
.flatMap(window -> window.groupBy(Auction::getItem))
.flatMap(longAuctionGroupedFlux -> longAuctionGroupedFlux.reduce(new ItemDumpStats(), this::calculateStats))
.subscribe(itemDumpStatsMono -> log.info(itemDumpStatsMono.toString()));
这是我的代码,该代码不起作用。没有错误,没有结果。调试后,我发现减少流时代码被卡在第二个flatMap上。我认为问题在于flatMap合并,卡在Mono解析上。现在有人如何解决此问题并仅使用单个订户?
如何复制,您可以使用其他类或创建一个类。小尺寸正在工作,大尺寸正在消亡
List<Auction> auctionList = new ArrayList<>();
for (int i = 0;i<100000;i++){
Auction a = new Auction((long) i, "test");
a.setItem((long) (i%50));
auctionList.add(a);
}
Flux.fromIterable(auctionList).groupBy(Auction::getId).flatMap(longAuctionGroupedFlux ->
longAuctionGroupedFlux.reduce(new ItemDumpStats(), (itemDumpStats, auction) -> itemDumpStats)).collectList().subscribe(itemDumpStats -> System.out.println(itemDumpStats.toString()));
这种方法是立竿见影的,但我使用了3个订阅者
Flux.fromIterable(auctionList)
.groupBy(Auction::getId)
.subscribe(
auctionIdAuctionGroupedFlux -> auctionIdAuctionGroupedFlux.reduce(new ItemDumpStats(), (itemDumpStats, auction) -> itemDumpStats).subscribe(itemDumpStats -> System.out.println(itemDumpStats.toString()
)
));
答案 0 :(得分:1)
我认为您描述的行为与groupBy
和flatMap
链接之间的交互有关。
查看groupBy文档。它指出:
需要使组耗尽并向下游消耗,以便groupBy正常工作。值得注意的是,当标准产生大量组时,如果组没有在下游适当使用,则可能导致挂起(例如,由于maxConcurrency参数设置得太低的flatMap)。
默认情况下,maxConcurrency (flatMap)
设置为256(我检查了3.2.2的源代码)。所以,
选择超过256个组可能导致执行挂起(尤其是当所有执行发生在同一线程上时)。
以下代码有助于理解将操作员groupBy和flatMap链接在一起时发生的情况:
@Test
public void groupAndFlatmapTest() {
val groupCount = 257;
val groupSize = 513;
val list = rangeClosed(1, groupSize * groupCount).boxed().collect(Collectors.toList());
val source = Flux.fromIterable(list)
.groupBy(i -> i % groupCount)
.flatMap(Flux::collectList);
StepVerifier.create(source).expectNextCount(groupCount).expectComplete().verify();
}
该代码的执行挂起。将groupCount
更改为256或更小会使测试通过(对于groupSize
的每个值)。
因此,关于您的原始问题,很有可能正在使用键选择器Auction::getItem
创建大量组。
答案 1 :(得分:0)
添加了parallel
已解决的问题,但我正在寻找答案,为什么可以大大降低缓慢的flatMap。