溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

WebFlux服務(wù)編排怎么使用

發(fā)布時(shí)間:2023-05-05 10:45:48 來源:億速云 閱讀:91 作者:iii 欄目:開發(fā)技術(shù)

這篇“WebFlux服務(wù)編排怎么使用”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“WebFlux服務(wù)編排怎么使用”文章吧。

    WebFlux服務(wù)編排

    WebFlux 服務(wù)編排是指使用 WebFlux 框架來編排多個(gè)異步服務(wù)的執(zhí)行順序和數(shù)據(jù)流動(dòng),從而構(gòu)建出一個(gè)完整的、基于事件驅(qū)動(dòng)的響應(yīng)式應(yīng)用程序。

    WebFlux服務(wù)編排的優(yōu)勢(shì)如下:

    • 高性能:WebFlux基于響應(yīng)式編程模型,可以使用少量的線程處理大量的請(qǐng)求,從而提高系統(tǒng)的并發(fā)能力和吞吐量。

    • 異步處理:WebFlux可以異步處理請(qǐng)求和響應(yīng),避免線程的阻塞和等待,提高系統(tǒng)的并發(fā)能力和性能。

    • 高可靠性:WebFlux基于事件驅(qū)動(dòng)的編程模型,可以更好地處理錯(cuò)誤和異常,從而提高系統(tǒng)的可靠性和穩(wěn)定性。

    • 簡(jiǎn)潔清晰:WebFlux的代碼簡(jiǎn)潔清晰,可以使用函數(shù)式編程風(fēng)格來編寫業(yè)務(wù)邏輯,提高代碼的可讀性和可維護(hù)性。

    • 可擴(kuò)展性:WebFlux可以輕松地集成其他的響應(yīng)式組件和服務(wù),例如Reactive Streams、Spring Cloud、RSocket等,從而提高系統(tǒng)的可擴(kuò)展性和靈活性。

    綜上所述,WebFlux服務(wù)編排可以幫助我們構(gòu)建高性能、高可靠性、可擴(kuò)展性強(qiáng)的響應(yīng)式應(yīng)用程序,提高系統(tǒng)的并發(fā)能力和性能,從而更好地滿足現(xiàn)代應(yīng)用程序的需求。

    一個(gè)示例

    public Mono> getOrderDetails(String orderId) {
        return Mono.fromCallable(() -> {
            // 查詢訂單基本信息
            return "order info";
        })
        .flatMap(orderInfo -> {
            // 查詢訂單商品信息
            return Mono.fromCallable(() -> {
                return "order item info";
            });
        })
        .flatMap(orderItemInfo -> {
            // 查詢訂單配送信息
            return Mono.fromCallable(() -> {
                return "order delivery info";
            });
        })
        .flatMap(orderDeliveryInfo -> {
            // 查詢訂單支付信息
            return Mono.fromCallable(() -> {
                return "order payment info";
            });
        });
    }

    為什么使用 fromCallable,就是上面說的,WebFlux 編排的是異步服務(wù),而不是同步服務(wù)。

    但是實(shí)際線上不要使用 fromCallable,會(huì)導(dǎo)致創(chuàng)建很多個(gè)線程,高并發(fā)場(chǎng)景下會(huì)導(dǎo)致資源競(jìng)爭(zhēng)激烈,從而服務(wù)性能急劇下降。

    1 串行

    1.1 不需要 invoker1 的結(jié)果

    long start = System.currentTimeMillis();
    Mono<String> invoke1 = Invoker1.invoke1();
    Mono<String> result = invoke1.flatMap(p -> Invoker2.invoke2())
          .map(s -> {
             return s.toString();
          });
    // result: invoker2, 耗時(shí):3592(串行)
    System.out.println("result: " + result.block() + ", 耗時(shí):" + (System.currentTimeMillis() - start));

    1.2 需要返回 invoker1 的結(jié)果

    long start = System.currentTimeMillis();
    Mono<String> invoke1 = Invoker1.invoke1();
    Mono<String> result = invoke1.flatMap(p -> {
       return Invoker2.invoke2().map(s -> {
          return p + s;
       });
    });
    // result: invoker1invoker2, 耗時(shí):3554(串行)
    System.out.println("result: " + result.block() + ", 耗時(shí):" + (System.currentTimeMillis() - start));

    2 并行

    2.1 zip 方法

    zip() 方法可以一次組裝任意個(gè)Mono,適用于有多個(gè)Mono的情況

    long start = System.currentTimeMillis();
    Mono<String> invoke1 = Invoker1.invoke1();
    Mono<String> invoker2 = Invoker2.invoke2();
    Mono<String> result = Mono.zip(invoke1, invoker2)
          .map(s-> {
             String t1 = s.getT1();
             String t2 = s.getT2();
             return String.format("invoke1:%s, invoke2: %s", t1, t2);
          });
    // invoker1invoker2耗時(shí):2650 (并行)
    System.out.println("result: " + result.block() + ",耗時(shí):" + (System.currentTimeMillis() - start));

    2.2 zipWith 方法

    zipWith() 每次組裝一個(gè)Mono對(duì)象,使用于組裝Mono個(gè)數(shù)比較少的情況。

    long start = System.currentTimeMillis();
    Mono<String> invoke1 = Invoker1.invoke1();
    Mono<String> invoker2 = Invoker2.invoke2();
    Mono<String> result = invoke1.zipWith(invoker2)
          .map(s -> {
             return String.format("invoke1:%s, invoke2: %s", s.getT1(), s.getT2());
          });
    // invoker1invoker2耗時(shí):2469 (并行)
    System.out.println(result.block() + ",耗時(shí):" + (System.currentTimeMillis() - start));

    3 前提

    這里的 invoker 就是第三方系統(tǒng)調(diào)用。

    保證 invoker 是在獨(dú)立的線程中執(zhí)行,這樣 invoker 不會(huì)影響業(yè)務(wù)處理。

    public class Invoker1 {
       public static Mono<String> invoke1() {
          return Mono.
                fromSupplier(() -> {
                   try {
                      Thread.sleep(1000);
                   } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                   }
                   return "invoker1";
                })
                .subscribeOn(Schedulers.parallel())
                .doOnError(e -> {
                   System.out.println("error invoker1");
                });
       }
    }
    public class Invoker2 {
       public static Mono<String> invoke2() {
          return Mono.fromSupplier(() -> {
                   try {
                      Thread.sleep(2000);
                   } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                   }
                   return "invoker2";
                })
                .subscribeOn(Schedulers.parallel())
                .doOnError(e -> {
                   System.out.println("error invoker2");
                });
       }
    }

    以上就是關(guān)于“WebFlux服務(wù)編排怎么使用”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI