简体   繁体   English

如何使用 Mono & Flux 限制并发 http 请求

[英]How to limit concurrent http requests with Mono & Flux

I want to handle Flux to limit concurrent HTTP requests made by List of Mono .我想处理Flux以限制 Mono 列表发出的并发Mono请求。

When some requests are done (received responses), then service requests another until the total count of waiting requests is 15.当一些请求完成(收到响应)时,服务会请求另一个请求,直到等待请求的总数为 15。

A single request returns a list and triggers another request depending on the result.单个请求返回一个列表并根据结果触发另一个请求。

At this point, I want to send requests with limited concurrency.此时,我想以有限的并发发送请求。 Because consumer side, too many HTTP requests make an opposite server in trouble.因为消费者端,过多的HTTP请求使得对端服务器陷入困境。

I used flatMapMany like below.我像下面那样使用flatMapMany

public Flux<JsonNode> syncData() {
    return service1
        .getData(param1)
        .flatMapMany(res -> {
                List<Mono<JsonNode>> totalTask = new ArrayList<>();
                Map<String, Object> originData = service2.getDataFromDB(param2);
                res.withArray("data").forEach(row -> {
                       String id = row.get("id").asText();
                       if (originData.containsKey(id)) {
                           totalTask.add(service1.updateRequest(param3));
                       } else {
                            totalTask.add(service1.deleteRequest(param4));
                       }
                       originData.remove(id);
                });
                for (left) {
                    totalTask.add(service1.createRequest(param5));
                }
                return Flux.merge(totalTask);
        });
}
void syncData() {
    syncDataService.syncData().????;
}

I tried chaining .window(15) , but it doesn't work.我尝试链接.window(15) ,但它不起作用。 All the requests are sent simultaneously.所有请求同时发送。

How can I handle Flux for my goal?我如何处理Flux以达到我的目标?

I am afraid Project Reactor doesn't provide any implementation of either rate or time limit.恐怕 Project Reactor 不提供任何速率或时间限制的实现。

However, you can find a bunch of 3rd party libraries that provide such functionality and are compatible with Project Reactor.但是,您可以找到一堆提供此类功能并与 Project Reactor 兼容的 3rd 方库。 As far as I know, resilience4-reactor supports that and is also compatible with Spring and Spring Boot frameworks.据我所知, resilience4-reactor支持这一点,并且还与 Spring 和 Spring Boot 框架兼容。

The RateLimiterOperator checks if a downstream subscriber/observer can acquire a permission to subscribe to an upstream Publisher. RateLimiterOperator检查下游订阅者/观察者是否可以获得订阅上游发布者的权限。 If the rate limit would be exceeded, the RateLimiterOperator could either delay requesting data from the upstream or it can emit a RequestNotPermitted error to the downstream subscriber.如果超过速率限制, RateLimiterOperator可以延迟从上游请求数据,也可以向下游订阅者发出RequestNotPermitted错误。

RateLimiter rateLimiter = RateLimiter.ofDefaults("name");
Mono.fromCallable(backendService::doSomething)
    .transformDeferred(RateLimiterOperator.of(rateLimiter))

More about RateLimiter module itself here: https://resilience4j.readme.io/docs/ratelimiter更多关于 RateLimiter 模块本身的信息: https : //resilience4j.readme.io/docs/ratelimiter

flatMap takes a concurrency parameter: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#flatMap-java.util.function.Function-int- flatMap采用concurrency参数: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#flatMap-java.util.function.Function-int-


Mono<User> getById(int userId) { ... }

Flux.just(1, 2, 3, 4).flatMap(client::getById, 2)

will limit the number of concurrent requests to 2.将并发请求数限制为 2。

You can use limitRate on a Flux.您可以在 Flux 上使用limitRate you need to probably reformat your code a bit but see docs here: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#limitRate-int-您可能需要稍微重新格式化您的代码,但请参阅此处的文档: https : //projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#limitRate-int-

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

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