簡體   English   中英

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

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

我正在學習 webflux 和 reactor。 得到以下三種測試方法。 “documentOperations.findById”和“documentOperations.delete”是兩個數據庫操作。 我知道 test1 很糟糕,因為兩個數據庫操作放在一個異步方法中。 我的問題是:
test2 和 test3 對系統性能的影響是否相同? 或者換句話說,哪個更好?

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();
            });
}

基於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());
}

上面的例子都不好。 您所有的數據庫調用都返回具體類型,這意味着它們都是阻塞調用。

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

如果它是非阻塞的,則返回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");

如果您必須使用阻塞數據庫,例如 oracle 數據庫等。您需要將它放在它自己的整個線程上,這樣它就不會阻塞任何主工作線程。 這可以通過調度程序來完成。 所以在這個例子中,當客戶端訂閱時,它將被放置在一個單獨的線程上。

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

所以對於你的例子:

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 文檔 - 包裝阻塞調用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM