简体   繁体   English

使用 webflux 和 reactor 的正确方法是什么

[英]What's the correct way to use webflux and reactor

I'm leaning webflux and reactor.我正在学习 webflux 和 reactor。 Got three test methods as below.得到以下三种测试方法。 "documentOperations.findById" and "documentOperations.delete" are two database operations. “documentOperations.findById”和“documentOperations.delete”是两个数据库操作。 I know test1 is bad as the two db operations are placed in one async method.我知道 test1 很糟糕,因为两个数据库操作放在一个异步方法中。 My question is:我的问题是:
Do test2 and test3 have the same impact to system performace? test2 和 test3 对系统性能的影响是否相同? Or in other words, which one is better?或者换句话说,哪个更好?

private Mono<ServerResponse> test1(ServerRequest request, Contexts contexts) {
    return request.body(bodyDocumentExtractor)
            .flatMap(doc -> {
                Document document = documentOperations.findById(doc.getId());
                documentOperations.delete(document.getId());
                return ServerResponse.noContent().build();
            });
}

private Mono<ServerResponse> test2(ServerRequest request, Contexts contexts) {
    return request.body(bodyDocumentExtractor)
            .flatMap(doc -> {
                return Mono.just(documentOperations.findById(doc.getId()))
                        .flatMap(document -> {
                            documentOperations.delete(document.getId());
                            return ServerResponse.noContent().build();
                        });
            });
}

private Mono<ServerResponse> test3(ServerRequest request, Contexts contexts) {
    return request.body(bodyDocumentExtractor)
            .flatMap(doc -> {
                return Mono.just(documentOperations.findById(doc.getId()));
            }).flatMap(document -> {
                documentOperations.delete(document.getId());
                return ServerResponse.noContent().build();
            });
}

I would expect the code to look something along the lines of the code below based on the assumption that DocumentOperations is reactive.基于DocumentOperations是反应性的假设,我希望代码看起来像下面的代码行。

private Mono<ServerResponse> test3(ServerRequest request, Contexts contexts) {
    return request.body(bodyDocumentExtractor)
            .flatMap(doc -> documentOperations.findById(doc.getId()))
            .flatMap(document -> documentOperations.delete(document.getId()))
            .then(ServerResponse.noContent().build());
}

None of the examples above are good.上面的例子都不好。 All your database calls return concrete types which means that they are all blocking calls.您所有的数据库调用都返回具体类型,这意味着它们都是阻塞调用。

// returns the concrete type
// thread does the call, needs to wait until we get the value (document)
Document document = documentOperations.findById("1");

If it is non blocking it returns a Mono<T> or a Flux<T> .如果它是非阻塞的,则返回Mono<T>Flux<T>

// Returns a mono, so we know it's not blocking. 
// We can chain on actions with for example flatMap etc.
Mono<Document> document = documentOperations.findById("1");

If you have to use a blocking database like for instance oracle database etc. You need to place this on its entire own thread, so that it doesn't block any of the main worker threads.如果您必须使用阻塞数据库,例如 oracle 数据库等。您需要将它放在它自己的整个线程上,这样它就不会阻塞任何主工作线程。 This can be done with a scheduler.这可以通过调度程序来完成。 So in this example when a client subscribes it will be placed on a separate thread.所以在这个例子中,当客户端订阅时,它将被放置在一个单独的线程上。

Mono<Document> document = Mono.fromCallable(() -> documentOperations.findById("1"))
    .subscribeOn(Schedulers.boundedElastic());;

So for your example:所以对于你的例子:

private Mono<ServerResponse> test3(ServerRequest request, Contexts contexts) {
    return request.body(bodyDocumentExtractor)
        .flatMap(doc -> Mono.fromCallable(() -> documentOperations.findById(doc.getId()))
        .flatMap(document -> Mono.fromCallable(() -> documentOperations.delete(document.getId()))
                .then(ServerResponse.noContent().build());
        ).subscribeOn(Schedulers.boundedElastic());
}

Reactor documentation - Wrap blocking calls Reactor 文档 - 包装阻塞调用

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

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