提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
概述
Spring5中重要的变化是把响应式编程的思想应用到了框架的各个方面如Spring WebFlux, Spring Data和Spring Cloud Gateway。Spring5 的响应式编程默认以Reactor库为基础。Reactor内部提供了Flux和Mono两个代表异步数据系列的核心组件,其中,Mono返回0或1个元素,即单个对象;Flux则返回N个元素,即List列表对象。它使开发人员能够方便快捷的构建异步非阻塞的应用程序。响应式编程应用场景很多,本文结合其异步非阻塞的特点列出以下应用场景:
一、请求异步处理
适用于发送手机短信、发送邮件、图片上传等耗时较长的场景。
示例代码:
Mono.just(params).publishOn(Schedulers.elastic())
.flatMap(v -> doStep1(v))
.map(v -> doStep2(v))
.flatMap(v -> doStep3(v));
二、API组合
在前后端分离的开发模式中,有时前端需要的接口后端只是提供了多个功能单一的接口,前端需要挨个调用,然后把返回的结果进行合并,处理起来比较麻烦,这时后端可以通过API组合的方式对前端提供服务。
1.项目内部Service API组合
需求:根据订单号获取订单信息及对应的物流信息
如果查询订单信息和物流信息的服务都在一个项目中,可以通过异步并行查询方式提高性能。
项目仅需要引入Reactor、RxJava等异步框架即可
示例代码如下:
@Service
public class OrderService {
public String getOrderInfo(String orderId) {
try {
TimeUnit.SECONDS.sleep(50);
} catch (InterruptedException e) {
return "Error during thread sleep";
}
return orderId+"订单信息: 烟台苹果10斤";
}
}
@Service
public class LogisticsService {
public String getLogisticsInfo(String orderId) {
try {
TimeUnit.SECONDS.sleep(50);
} catch (InterruptedException e) {
return "Error during thread sleep";
}
return orderId +"物流信息: 烟台->潍坊中转->济南";
}
}
class DemojarApplicationTests {
@Autowired
private OrderService orderService;
@Autowired
private LogisticsService logisticsService;
void parrallelService() {
String orderId="DJ0001";
long start=System.currentTimeMillis();
//异步查询
Mono<String> orderInfo =Mono.just(orderId).publishOn(Schedulers.elastic())
.map(s->this.orderService.getOrderInfo(s));
Mono<String> logisticsInfo =Mono.just(orderId).publishOn(Schedulers.elastic())
.map(s->{return this.logisticsService.getLogisticsInfo(s);});
//合并查询结果
String orderLogisticsInfo = Mono.zip(orderInfo,logisticsInfo,(a,b)->{
//合并结果生成订单物流信息
return a+"\n "+b;
}).block();
long end=System.currentTimeMillis();
System.out.println("耗时"+(end -start)/1000+"s");
System.out.println("result\n "+orderLogisticsInfo);
}
2.微服务API组合
利用Webflux中的WebClient实现异步rest服务调用,示例代码如下:
WebClient client = WebClient.create();
String orderId="JD0001";
Mono<String> orderInfo = client.get().uri("http://localhost:8080/order/{id}",orderId).retrieve().bodyToMono(String.class);
Mono<String> logisticsInfo = client.get().uri("http://localhost:8080/logistics/{id}",orderId).retrieve().bodyToMono(String.class);
String orderLogisticsInfo = Mono.zip(orderInfo,logisticsInfo,(a,b)->{
return a+" "+b;
}).block();
3.在API网关中进行API组合
可利用Spring Cloud Gateway做为网关并进行API组合
二、全栈响应式微服务
WebFlux + R2DBC +spring cloud gateway,如果需要用到消息队列可引入 reactive spring cloud stream。
R2DBC(Reactive Relational Database Connectivity)是一个为响应式编程设计的数据库连接规范。它允许你使用响应式编程模型与关系型数据库进行交互,从而充分利用数据库的性能。R2DBC 提供了非阻塞的数据库访问方式,与 WebFlux 配合使用可以实现从数据库到 Web 层的全栈响应式编程。
Spring Cloud Gateway 是 Spring Cloud 生态系统中的一个项目,它提供了用于构建微服务网关的功能。网关通常用于处理微服务架构中的路由、安全性、监控和限流等任务。Spring Cloud Gateway 支持 WebFlux,因此可以利用响应式编程模型来处理大量的并发请求。
全栈响应式微服务是一种基于响应式编程的微服务架构。在全栈响应式微服务中,整个技术栈,包括前端、后端、数据库等,都采用了响应式编程模型。这种架构可以获得异步、响应性、弹性、快速恢复、背压等系统特性,同时在资源占用、高并发、高吞吐、异步处理场景中具有更强的优势。
全栈响应式微服务的优势在于:
异步非阻塞:全栈响应式微服务基于响应式编程模型,可以在整个技术栈中实现异步非阻塞的处理方式。这种方式能够更好地利用多核CPU的硬件资源,提高系统的并发处理能力和吞吐量。
弹性扩展:由于全栈响应式微服务采用了响应式编程模型,系统可以根据实际需求进行弹性扩展。当流量增加时,可以轻松地增加更多的服务实例来处理请求,保持系统的稳定性和高性能。
快速恢复:全栈响应式微服务具有快速恢复的能力。当某个服务实例出现故障时,系统可以迅速将其替换为新的服务实例,保证服务的连续性和可用性。
背压机制:在全栈响应式微服务中,通过引入背压机制,可以有效地控制数据流的速度,避免系统过载。当数据流速度过快时,背压机制可以减缓数据流的速度,保证系统的稳定性和可靠性。
为了实现全栈响应式微服务,需要选择合适的技术栈和框架。前端可以采用如React、Vue等响应式前端框架,后端可以采用如Spring WebFlux等响应式后端框架,数据库可以采用如R2DBC等响应式数据库访问技术。同时,还需要结合容器化技术、持续集成/持续部署(CI/CD)等技术手段来支撑微服务的快速迭代和交付。
需要注意的是,全栈响应式微服务虽然具有很多优势,但在实际应用中也需要根据具体业务场景和需求进行综合考虑。例如,在某些场景下,传统的同步阻塞式处理方式可能更加适合。因此,在选择是否采用全栈响应式微服务时,需要进行充分的调研和评估。
总结
WebFlux的响应式编程模型使得在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。这种特性使得WebFlux在处理大量并发请求时具有更高的效率和伸缩性。
具体来说,WebFlux的响应式编程模型可以在以下场景中发挥重要作用:
- 高并发场景:WebFlux的异步非阻塞特性使其在处理大量并发请求时具有优势。通过使用Mono和Flux,可以轻松地处理大量的数据流,而无需担心线程阻塞或资源耗尽的问题。
- 实时数据处理:WebFlux的响应式编程模型使得在数据流上进行实时处理成为可能。例如,可以使用WebFlux来处理实时数据流,如传感器数据、股票行情等,并进行实时分析和处理。
- 复杂数据处理:对于复杂的数据处理逻辑,如数据转换、过滤、聚合等,WebFlux的响应式编程模型可以提供更为简洁和高效的解决方案。通过使用操作符链式调用,可以轻松地实现复杂的数据处理逻辑。
- 分布式系统:在分布式系统中,各个节点之间的通信和协作非常重要。WebFlux的响应式编程模型可以提供一种灵活且高效的方式来处理节点之间的数据流,从而实现更加健壮和可扩展的分布式系统。
总之,Spring 5的WebFlux响应式编程模型为处理大量并发请求、实时数据处理、复杂数据处理以及分布式系统等场景提供了有效的解决方案。通过充分利用其异步非阻塞特性和数据流处理能力,可以显著提高系统的吞吐量和伸缩性。