WebFlux 服务编排使用优势详解
作者:六七十三 发布时间:2021-11-27 07:48:45
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");
});
}
}
来源:https://juejin.cn/post/7225902886944751677


猜你喜欢
- 在Spring4之后,要使用注解开发,必须要保证aop的包导入了使用注解需要导入context约束,增加注解的支持!<?xml ver
- 1、首先创建一个按钮<Buttonandroid:id="@+id/click"android:layout_wi
- 问题描述:图片加载后显示,然后进行删除操作时提示“……正由另一进程使用,因此该进程无法访问该文件。……”解决办法:原代码:iml.Image
- 本文实例讲述了Winform实现调用asp.net数据接口的方法,分享给大家供大家参考。具体实现方法如下:一、问题:最近一个WPF项目需要改
- 1、Fragment的静态使用Fragment是作为Activity的UI的一部分,它内嵌在Activity中,多个Fragment可以把一
- AnimationListener听名字就知道是对Animation设置 * ,说简单点就是在Animation动画效果开始执行前,执行完毕
- 我们在使用SpringData JPA框架时,进行条件查询,如果是固定条件的查询,我们可以使用符合框架规则的自定义方法以及@Query注解实
- 将此实例的子字符串中所有指定字符的匹配项替换为其他指定字符。 命名空间:System.Text 程序集:mscorl
- 一、使用Json.NetJson.Net是支持序列化和反序列化DataTable、DataSet、Entity Framework和Enti
- 先写在前面,这说的Settings加载选项是指Settings这个应用显示在主界面的选项,这个修改需要对系统源码进行修改。Android 7
- 简介在 io 包中,提供了两个与平台无关的数据操作流:数据输出流(DataOutputStream)、数据输入流 (DataInputStr
- 一、简介线程安全概念:线程安全是指在当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出
- 一、基本定义Arrays类,全路径java.util.Arrays,主要功能为操作数组,Arrays类的所有方法均为静态方法,所以调用方式全
- Androidstudio音乐播放器,供大家参考,具体内容如下实现目的:利用广播在myapplication中原本button点我暂停按钮是
- 本文是一个 Spring 扩展支持 SPEL 的简单模式,方便第三方通过 Spring 提供额外功能。简化版方式这种方式可以在任何能获取Ap
- 实现代码超简单,具体实现方法如下:有时候当我们的游戏人物遇敌时,我们需我怪物随机根据概率选择处理方式,如下:1、50%的机会友好的问候2、2
- 使用 AppbarLayout 和 MotionLayout 实现常用的布局效果前文我们讲了协调滚动的一些定义方式,我们在开发中常用的几种效
- 前言在Flutter实际开发中,大家可能会遇到flutter框架中提供的widget达不到我们想要的效果,这时就需要我们去自定义widget
- 说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史远比Java久
- 本文实例讲述了C#多线程中的异常处理操作。分享给大家供大家参考,具体如下:常规Thread中处理异常使用Thread创建的子线程,需要在委托