Java Mutiny-如何将项目分组以按块发送请求

Java Mutiny-如何将项目分组以按块发送请求,java,asynchronous,vert.x,quarkus,mutiny,Java,Asynchronous,Vert.x,Quarkus,Mutiny,我正在使用Mutiny扩展(用于Quarkus),我不知道如何处理这个问题 我想以异步方式发送许多请求,所以我已经阅读了Mutiny扩展。但是服务器关闭了连接,因为它接收了数千个连接 因此,我需要: 按块发送请求 在所有请求发送后,执行操作 我一直在使用Uni object来组合所有响应,如下所示: Uni<Map<Integer, String>> uniAll = Uni.combine() .all() .unis(list) .combine

我正在使用Mutiny扩展(用于Quarkus),我不知道如何处理这个问题

我想以异步方式发送许多请求,所以我已经阅读了Mutiny扩展。但是服务器关闭了连接,因为它接收了数千个连接

因此,我需要:

  • 按块发送请求
  • 在所有请求发送后,执行操作
我一直在使用Uni object来组合所有响应,如下所示:

Uni<Map<Integer, String>> uniAll = Uni.combine()
   .all()
   .unis(list)
   .combinedWith(...);
此代码并行发送所有请求,以便服务器关闭连接

我正在使用多对象组,但我不知道如何使用它(在Mutiny文档中,我找不到任何示例)

我现在就是这样做的:

          //Launch 1000 request
          for (int i=0;i<1000;i++) {
            multi = client.getAbs("https://api.*********.io/jokes/random")
                      .as(BodyCodec.jsonObject())
                      .send()
                      .onItem().transformToMulti(
                              array -> Multi.createFrom()
                                       .item(array.body().getString("value")))
                                       .group()
                                       .intoLists()
                                       .of(100)
                                       .subscribe()
                                       .with(a->{
                                         System.out.println("Value: "+a);
                                        });
          }

响应一个接一个地打印,当前100个项目组结束时,它打印下一组。问题出在哪里?有连续的请求,需要花费大量时间

我想我已经接近解决方案了,但我需要知道,如何只在100组中发送并行请求,因为如果我将:

subscribe().with()

所有的请求都是并行发送的(而不是以100为一组发送)

我认为您创建的多个请求是错误的,使用它会更容易:

Multi<String> multiOfJokes = Multi.createFrom().emitter(multiEmitter -> {
        for (int i=0;i<1000;i++) {
            multiEmitter.emit(i);
        }
        multiEmitter.complete();
    }).onItem().transformToUniAndMerge(index -> {
        return Uni.createFrom().item("String" + index);
    })
Multi-multiof=Multi.createFrom().emitter(multiEmitter->{
对于(int i=0;i{
返回Uni.createFrom().item(“字符串”+索引);
})
使用这种方法,它应该并行处理调用。 现在的问题是如何将其列为一个列表

分组工作正常 我使用以下代码运行它:

Random random = new Random();
    Multi<Integer> multiOfInteger = Multi.createFrom().emitter(multiEmitter -> {
        for (Integer i=0;i<1000;i++) {
            multiEmitter.emit(i);
        }
        multiEmitter.complete();
    });
    Multi<String> multiOfJokes = multiOfInteger.onItem().transformToUniAndMerge(index -> {
        if (index % 10 == 0 ) {
            Duration delay = Duration.ofMillis(random.nextInt(100) + 1);
            return Uni.createFrom().item("String " + index  + " delayed").onItem()
                    .delayIt().by(delay);
        }
        return Uni.createFrom().item("String" + index);
    }).onCompletion().invoke(() -> System.out.println("Completed"));
    Multi<List<String>> multiListJokes = multiOfJokes
            .group().intoLists().of(100)
            .onCompletion().invoke(() -> System.out.println("Completed"))
            .onItem().invoke(strings -> System.out.println(strings));
    multiListJokes.collect().asList().await().indefinitely();
Random Random=new Random();
Multi-multiOfInteger=Multi.createFrom().emitter(multiEmitter->{
对于(整数i=0;i{
如果(索引%10==0){
持续时间延迟=百万的持续时间(random.nextInt(100)+1);
返回Uni.createFrom().item(“字符串”+索引+“延迟”).onItem()
.delayIt().by(delay);
}
返回Uni.createFrom().item(“字符串”+索引);
}).onCompletion().invoke(()->System.out.println(“已完成”);
Multi-MultiList笑话=多个笑话
.group().intoLists().of(100)
.onCompletion().invoke(()->System.out.println(“已完成”))
.onItem().invoke(strings->System.out.println(strings));
MultiListJones.collect().asList().await().Unlimited();
您将获得字符串的列表

我不知道,您打算如何将列表发送到后端。 但是,您可以通过以下两种方式之一:

  • 调用(异步执行)
  • 写自己的订阅者(实现订阅者)方法是直接的。 如您批量请求所需
我希望你以后能更好地理解它

PS:链接到我学习所有这些的指南:

在使用Vert.x WebClient时,可以使用
setMaxPoolSize()配置最大并发性
要想做你想做的事情,你需要1000个请求的流,并将它们分组到100个列表中。然后,对于每个组,发出并处理响应。现在,它只创建1000个多请求,所有请求发出一个请求,得到结果,根据我所看到的,将响应分组到100个组中。因此,肯定不是你所描述的。So、 我可以将1000个请求添加到一个多对象列表中,然后创建一个多表单并使用该列表设置项目,然后将其分组到另一个100个列表中,然后订阅该组吗?因为我不知道如何将1000个请求列表到100个列表中.group()..“``嗨@Clement,我已经用一种新的方法更新了我的帖子。我想我已经接近解决方案了,但是请求是一个接一个地发送的,所以我想我需要请求以100人一组的方式并行发送。ThxHi,thx供您回复。我明白,问题是在该解决方案中适合Vert.x WebClient,因为当我尝试订阅时t、 调用以并行方式发送。我以为您想将其并行化。如果没有,您可以在一个简单的映射中替换TransformToUnianedMerge。然后它应该再次是串行的。或者我不明白您对webclient的意思。如果您使用Quarkus生成webclient,您不需要考虑它。请求总是以并行方式处理。是的,我不知道但是我想使用mutiny,我需要一个异步扩展来进行调用。在这种情况下,我使用Vert.X WebClient这是一个HTTP异步扩展。我也可以使用异步HTTP扩展。当我在p中启动调用时并行和异步,一切似乎都正常。然而,问题是客户端启动了数千个请求,而服务器引发了一个“封闭连接”异常,所以我想以1000个块的形式启动它们(p.e).ThxI我不确定,我的错误是什么,但是当你在将multi转换为Uni和merge部分使用web客户端时,你会得到并行调用。它应该限制为125个调用。因为这个函数有125个背压。因此,在开始时,它要求125个条目,然后在一个线程完成后,得到一个新条目。不应该有有上千个平行电话。你有任何链接,我可以读到限制应该是125吗?因为这是一个有趣的点。Thx
subscribe().with()
Multi<String> multiOfJokes = Multi.createFrom().emitter(multiEmitter -> {
        for (int i=0;i<1000;i++) {
            multiEmitter.emit(i);
        }
        multiEmitter.complete();
    }).onItem().transformToUniAndMerge(index -> {
        return Uni.createFrom().item("String" + index);
    })
Random random = new Random();
    Multi<Integer> multiOfInteger = Multi.createFrom().emitter(multiEmitter -> {
        for (Integer i=0;i<1000;i++) {
            multiEmitter.emit(i);
        }
        multiEmitter.complete();
    });
    Multi<String> multiOfJokes = multiOfInteger.onItem().transformToUniAndMerge(index -> {
        if (index % 10 == 0 ) {
            Duration delay = Duration.ofMillis(random.nextInt(100) + 1);
            return Uni.createFrom().item("String " + index  + " delayed").onItem()
                    .delayIt().by(delay);
        }
        return Uni.createFrom().item("String" + index);
    }).onCompletion().invoke(() -> System.out.println("Completed"));
    Multi<List<String>> multiListJokes = multiOfJokes
            .group().intoLists().of(100)
            .onCompletion().invoke(() -> System.out.println("Completed"))
            .onItem().invoke(strings -> System.out.println(strings));
    multiListJokes.collect().asList().await().indefinitely();