WebFlux 服务编排使用优势详解

 更新时间:2023年05月05日 09:16:23   作者:六七十三  
这篇文章主要为大家介绍了WebFlux 服务编排使用优势示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

WebFlux服务编排

WebFlux 服务编排是指使用 WebFlux 框架来编排多个异步服务的执行顺序和数据流动,从而构建出一个完整的、基于事件驱动的响应式应用程序。

WebFlux服务编排的优势如下:

  • 高性能:WebFlux基于响应式编程模型,可以使用少量的线程处理大量的请求,从而提高系统的并发能力和吞吐量。

  • 异步处理:WebFlux可以异步处理请求和响应,避免线程的阻塞和等待,提高系统的并发能力和性能。

  • 高可靠性:WebFlux基于事件驱动的编程模型,可以更好地处理错误和异常,从而提高系统的可靠性和稳定性。

  • 简洁清晰:WebFlux的代码简洁清晰,可以使用函数式编程风格来编写业务逻辑,提高代码的可读性和可维护性。

  • 可扩展性:WebFlux可以轻松地集成其他的响应式组件和服务,例如Reactive Streams、Spring Cloud、RSocket等,从而提高系统的可扩展性和灵活性。

综上所述,WebFlux服务编排可以帮助我们构建高性能、高可靠性、可扩展性强的响应式应用程序,提高系统的并发能力和性能,从而更好地满足现代应用程序的需求。

一个示例

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 编排的是异步服务,而不是同步服务。

但是实际线上不要使用 fromCallable,会导致创建很多个线程,高并发场景下会导致资源竞争激烈,从而服务性能急剧下降。

1 串行

1.1 不需要 invoker1 的结果

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

1.2 需要返回 invoker1 的结果

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, 耗时:3554(串行)
System.out.println("result: " + result.block() + ", 耗时:" + (System.currentTimeMillis() - start));

2 并行

2.1 zip 方法

zip() 方法可以一次组装任意个Mono,适用于有多个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耗时:2650 (并行)
System.out.println("result: " + result.block() + ",耗时:" + (System.currentTimeMillis() - start));

2.2 zipWith 方法

zipWith() 每次组装一个Mono对象,使用于组装Mono个数比较少的情况。

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耗时:2469 (并行)
System.out.println(result.block() + ",耗时:" + (System.currentTimeMillis() - start));

3 前提

这里的 invoker 就是第三方系统调用。

保证 invoker 是在独立的线程中执行,这样 invoker 不会影响业务处理。

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

以上就是WebFlux 服务编排使用优势详解的详细内容,更多关于WebFlux 服务编排优势的资料请关注脚本之家其它相关文章!

相关文章

  • spring监视器actuator配置应用

    spring监视器actuator配置应用

    这篇文章主要介绍了spring监视器actuator配置应用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Java排序算法中的插入排序算法实现

    Java排序算法中的插入排序算法实现

    这篇文章主要介绍了Java排序算法中的插入排序算法实现,插入排序是将数组中的数据分为两个区间,已排序区间和未排序区间,其中已排序区间初始只有一个元素,就是数组的第一个元素,需要的朋友可以参考下
    2023-12-12
  • Spring面向切面编程AOP详情

    Spring面向切面编程AOP详情

    这篇文章主要介绍了Spring面向切面编程AOP详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Java异步调用转同步方法实例详解

    Java异步调用转同步方法实例详解

    这篇文章主要介绍了Java异步调用转同步方法实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • springboot集成mybatisPlus+多数据源的实现示例

    springboot集成mybatisPlus+多数据源的实现示例

    这篇文章主要介绍了springboot集成mybatisPlus+多数据源的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • springboot2.6.3读取不到nacos上的配置文件问题

    springboot2.6.3读取不到nacos上的配置文件问题

    这篇文章主要介绍了springboot2.6.3读取不到nacos上的配置文件问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 详解IntelliJ IDEA 快捷键整合(大全)

    详解IntelliJ IDEA 快捷键整合(大全)

    这篇文章主要介绍了详解IntelliJ IDEA 快捷键整合,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-08-08
  • Maven打包并生成运行脚本的示例代码

    Maven打包并生成运行脚本的示例代码

    这篇文章主要介绍了Maven打包并生成运行脚本,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Spring系统属性及spring.properties配置文件示例详解

    Spring系统属性及spring.properties配置文件示例详解

    spring中有一个SpringProperties类,来保存spring的系统属性,本文结合实例代码对Spring系统属性及spring.properties配置文件相关知识给大家介绍的非常详细,需要的朋友参考下吧
    2023-07-07
  • Java实现读取163邮箱,qq邮箱的邮件内容

    Java实现读取163邮箱,qq邮箱的邮件内容

    这篇文章主要利用Java语言实现读取163邮箱和qq邮箱的邮件内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试
    2022-02-02

最新评论