当前位置:首页 > 科技  > 软件

快速掌握Spring异步请求接口,轻松解决并发问题

来源: 责编: 时间:2023-10-20 10:02:28 380观看
导读环境:SpringBoot2.7.121. 概述 在现代的互联网应用中,随着用户数量的不断增加和业务复杂性的提升,并发问题成为了开发中面临的重大挑战。传统的同步请求接口往往无法满足高并发场景的需要,不仅会阻塞调用线程,影响系

环境:SpringBoot2.7.12ORE28资讯网——每日最新资讯28at.com


1. 概述ORE28资讯网——每日最新资讯28at.com

      在现代的互联网应用中,随着用户数量的不断增加和业务复杂性的提升,并发问题成为了开发中面临的重大挑战。传统的同步请求接口往往无法满足高并发场景的需要,不仅会阻塞调用线程,影响系统的响应性能,而且还可能导致线程资源的浪费。为了解决这些问题,异步请求接口逐渐成为了开发者的首选。ORE28资讯网——每日最新资讯28at.com

在SpringBoot框架中,异步请求接口的创建和使用非常方便,能够让你轻松解决并发问题,提高系统的可维护性和响应性能。本文将介绍如何快速掌握SpringBoot异步请求接口,以轻松解决并发问题。ORE28资讯网——每日最新资讯28at.com

2. 异步请求接口优势ORE28资讯网——每日最新资讯28at.com

异步请求接口相比于传统同步请求具有以下优势:ORE28资讯网——每日最新资讯28at.com

  1. 非阻塞性:异步请求不会阻塞调用线程,而是在请求处理过程中继续执行其他任务或操作,从而提高了系统的并发性能和响应速度。
  2. 可用资源:异步请求可以释放占用的线程等资源,避免阻塞,等到结果产生再重新获取线程处理。这样能够节省资源,提高系统的资源利用率。
  3. 解耦:异步请求可以减少系统间的耦合度,使得不同的系统或服务之间可以更好地协同工作。因为请求处理过程中不会阻塞其他操作,可以更容易地实现分布式系统的调用。
  4. 异常处理:异步请求可以更容易地捕获、处理异常,因为请求处理的结果是在另一个线程中返回的,不会影响到主线程的执行流程。
  5. 控制流程:异步请求可以通过回调函数或者Promise等方式来控制流程,使得流程更加灵活和可扩展。

总之,异步请求接口具有上述优势,尤其是在高并发场景下,能够提高系统的性能和可用性,是解决并发问题的有效方法之一。ORE28资讯网——每日最新资讯28at.com

3. 应用场景ORE28资讯网——每日最新资讯28at.com

异步请求接口可以应用于以下场景:ORE28资讯网——每日最新资讯28at.com

  1. 高并发场景:在面对大量用户请求时,异步请求接口能够避免线程阻塞,提高系统的并发处理能力,减少等待时间,提升用户体验。
  2. 耗时操作处理:当需要进行一些耗时的操作,如网络请求、IO磁盘等操作时,采用异步请求接口可以避免阻塞主线程,提高系统的响应性能。
  3. 实时数据处理:对于实时性要求较高的应用,如实时数据流处理、实时股票交易等场景,采用异步请求接口能够快速处理数据,并实时反馈结果,提高系统的实时性。
  4. 异步业务流程:在某些业务流程中,涉及到多个异步任务,这些任务之间没有依赖关系,可以采用异步请求接口进行实现,提高系统的并发性和响应性能。
  5. API接口的调用:当需要对其他API接口进行调用时,特别是对于一些耗时较长的接口,采用异步请求接口可以提高系统的响应性能和资源利用率。

总之,异步请求接口适用于那些需要避免阻塞、提高系统响应性能、处理耗时操作和实时数据处理等场景中,能够提高系统的并发性能和资源利用率,减少系统瓶颈的出现。ORE28资讯网——每日最新资讯28at.com

接下来我们进入正文,在Spring环境下如何将我们的接口异步化。ORE28资讯网——每日最新资讯28at.com

4. 实战异步接口ORE28资讯网——每日最新资讯28at.com

Spring MVC 广泛集成了 Servlet 3.0 异步请求处理功能:ORE28资讯网——每日最新资讯28at.com

  • Controller方法中的 DeferredResult 和 Callable 返回值为单个异步返回值提供了基本支持。
  • Controller可以流式传输多个值,包括 SSE 和原始数据。
  • Controller可以使用反应式客户端和返回反应式类型来处理响应。


ORE28资讯网——每日最新资讯28at.com

4.1 DeferredResultORE28资讯网——每日最新资讯28at.com

一旦在 Servlet 容器中启用异步请求处理功能,控制器方法就可以用 DeferredResult 封装任何受支持的控制器方法返回值,如下例所示:ORE28资讯网——每日最新资讯28at.com

@GetMapping("/deferred")@ResponseBodypublic DeferredResult<Map<String, Object>> deferred(){  long start = System.currentTimeMillis() ;  System.out.printf("%s - 开始时间:%d%n", Thread.currentThread().getName(), start) ;  DeferredResult<Map<String, Object>> deferredResult = new DeferredResult<>();  // 为了演示方便直观,这里直接创建线程  new Thread(() -> {    try {      // 这里模拟耗时操作      TimeUnit.SECONDS.sleep(3) ;      // 将执行结果保存      Map<String, Object> result = new HashMap<>() ;      result.put("code", 1) ;      result.put("data", "你的业务数据") ;      deferredResult.setResult(result) ;    } catch (InterruptedException e) {}  }).start() ;  long end = System.currentTimeMillis() ;  System.out.printf("%s - 结束时间:%d%n", Thread.currentThread().getName(), end) ;  System.out.printf("总耗时:%d毫秒%n", (end - start)) ;  return deferredResult ;}

控制台输出结果:ORE28资讯网——每日最新资讯28at.com

2023-10-19 14:25:30.321  INFO 3884 --- [nio-8808-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 mshttp-nio-8808-exec-1 - 开始时间:1697696730335http-nio-8808-exec-1 - 结束时间:1697696730335总耗时:0毫秒

从结果看出,处理请求的tomcat线程几乎没有占用时间,线程被快速的释放,这样就可以去处理其它的连接请求,整个系统的吞吐量就的到了明显的提升。ORE28资讯网——每日最新资讯28at.com

Controller可以从不同的线程异步生成返回值。ORE28资讯网——每日最新资讯28at.com

4.2 CallableORE28资讯网——每日最新资讯28at.com

Controller可以用 java.util.concurrent.Callable 封装任何受支持的返回值,如下例所示:ORE28资讯网——每日最新资讯28at.com

@GetMapping("/callable")public Callable<Map<String, Object>> callable() {  long start = System.currentTimeMillis() ;  System.out.printf("%s - 开始时间:%d%n", Thread.currentThread().getName(), start) ;  Callable<Map<String, Object>> callable  = new Callable<Map<String, Object>>() {    public Map<String, Object> call() throws Exception {      Map<String, Object> result = new HashMap<>() ;      try {        // 这里模拟耗时操作        TimeUnit.SECONDS.sleep(3) ;        // 将执行结果保存        result.put("code", 1) ;        result.put("data", "你的业务数据") ;      } catch (InterruptedException e) {}      return result ;    }  } ;  long end = System.currentTimeMillis() ;  System.out.printf("%s - 结束时间:%d%n", Thread.currentThread().getName(), end) ;  System.out.printf("总耗时:%d毫秒%n", (end - start)) ;  return callable ;}

控制台输出结果:ORE28资讯网——每日最新资讯28at.com

http-nio-8808-exec-2 - 开始时间:1697697345385http-nio-8808-exec-2 - 结束时间:1697697345386总耗时:1毫秒

执行结果与上面一样。
注意:这里Callable中的代码执行是在系统默认的一个TaskExecutor线程池中运行,我们可以通过配置自己的TaskExecutor来执行。如下:
ORE28资讯网——每日最新资讯28at.com

@Beanpublic ThreadPoolTaskExecutor myAsyncTaskExecutor() {  // 配置ThreadPoolTaskExecutor相关参数,比如核心线程数等  return ... ;}

4.3 ResponseBodyEmitterORE28资讯网——每日最新资讯28at.com

你可以将 DeferredResult 和 Callable 用于单个异步返回值。如果要生成多个异步值并将其写入响应,该怎么办?本节将介绍如何做到这一点。ORE28资讯网——每日最新资讯28at.com

ResponseBodyEmitter 的返回值生成一个对象流,其中每个对象都会被 HttpMessageConverter 序列化并写入响应,如下例所示:ORE28资讯网——每日最新资讯28at.com

// 这里应该保存到一个集合中private ResponseBodyEmitter emitter ;@GetMapping("/emitter")public ResponseBodyEmitter emitter() throws Exception {  ResponseBodyEmitter bodyEmitter = new ResponseBodyEmitter(-1L);  this.emitter = bodyEmitter ;  return bodyEmitter;}// 可以不断调用该接口进行消息的发送@GetMapping("/sender")public void sender() throws Exception {  this.emitter.send(System.currentTimeMillis()) ;}// 调用该j接口后请求结束@GetMapping("/complete")public void complete() throws Exception {  this.emitter.complete() ;}

当访问/emitter接口时,浏览器会一直转圈,一直等待。只有调用了/complete接口后请求内容才会被发送到客户端并结束请求。ORE28资讯网——每日最新资讯28at.com

4.4 StreamingResponseBodyORE28资讯网——每日最新资讯28at.com

有时,绕过消息转换并直接流式传输到响应的 OutputStream(例如,文件下载)非常有用。为此,可以使用 StreamingResponseBody 返回值类型,如下例所示:ORE28资讯网——每日最新资讯28at.com

@GetMapping("/stream")public ResponseEntity<StreamingResponseBody> stream() {  long start = System.currentTimeMillis() ;  System.out.printf("%s - 开始时间:%d%n", Thread.currentThread().getName(), start) ;  // 内部执行还是用的系统内部的线程池  StreamingResponseBody stream = new StreamingResponseBody() {    @Override    public void writeTo(OutputStream outputStream) throws IOException {      outputStream.write(String.valueOf("当前时间: " + System.currentTimeMillis() + "<br/>").getBytes()) ;      try {        TimeUnit.SECONDS.sleep(1) ;      } catch (InterruptedException e) {}      outputStream.write(String.valueOf("当前时间: " + System.currentTimeMillis() + "<br/>").getBytes()) ;      try {        TimeUnit.SECONDS.sleep(1) ;      } catch (InterruptedException e) {}      outputStream.write(String.valueOf("当前时间: " + System.currentTimeMillis() + "<br/>").getBytes()) ;    }  };  MultiValueMap<String, String> headers = new HttpHeaders() ;  headers.add("Content-Type", "text/html;charset=UTF-8") ;  ResponseEntity<StreamingResponseBody> response = new ResponseEntity<StreamingResponseBody>(stream, headers , HttpStatus.OK) ;  long end = System.currentTimeMillis() ;  System.out.printf("%s - 结束时间:%d%n", Thread.currentThread().getName(), end) ;  System.out.printf("总耗时:%d毫秒%n", (end - start)) ;  return response ;}

控制台输出:ORE28资讯网——每日最新资讯28at.com

http-nio-8808-exec-1 - 开始时间:1697700256912http-nio-8808-exec-1 - 结束时间:1697700256915总耗时:3毫秒

tomcat线程非常短的时间内释放,这样就可以处理更多的请求,提升系统整体的吞吐量。这种最适合文件下载。ORE28资讯网——每日最新资讯28at.com

浏览器输出:ORE28资讯网——每日最新资讯28at.com

图片ORE28资讯网——每日最新资讯28at.com

4.5 SSEORE28资讯网——每日最新资讯28at.com

该方式请阅读《实时数据推送并非只有WebSocket一种选择》详细介绍了如何使用。
ORE28资讯网——每日最新资讯28at.com

4.6 基于反应式ORE28资讯网——每日最新资讯28at.com

Spring MVC 支持在控制器中使用反应式客户端库。这包括 spring-webflux 中的 WebClient 以及 Spring Data 反应式数据存储库等其他库。在这种情况下,从控制器方法中返回反应类型是很方便的。如下例所示:ORE28资讯网——每日最新资讯28at.com

@GetMapping("/mono")public Mono<Map<String, Object>> mono() {  long start = System.currentTimeMillis() ;  System.out.printf("%s - 开始时间:%d%n", Thread.currentThread().getName(), start) ;  Mono<Map<String, Object>> mono = Mono.defer(() -> {    try {      TimeUnit.SECONDS.sleep(3) ;    } catch (InterruptedException e) {}    Map<String, Object> result = new HashMap<>() ;    result.put("code", 1) ;    result.put("data", "你的业务数据") ;    return Mono.just(result) ;  }) ;  long end = System.currentTimeMillis() ;  System.out.printf("%s - 结束时间:%d%n", Thread.currentThread().getName(), end) ;  System.out.printf("总耗时:%d毫秒%n", (end - start)) ;  return mono ;}

控制台输出:ORE28资讯网——每日最新资讯28at.com

http-nio-8808-exec-2 - 开始时间:1697700686250http-nio-8808-exec-2 - 结束时间:1697700686251总耗时:1毫秒


ORE28资讯网——每日最新资讯28at.com

以上就是Spring中异步请求接口的实现方式。ORE28资讯网——每日最新资讯28at.com

异步请求接口是解决并发问题的有效方法之一,特别是在高并发、耗时操作、实时数据处理等场景中具有显著优势。通过异步请求,系统能够避免阻塞线程,提高系统的响应性能和资源利用率。ORE28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-14319-0.html快速掌握Spring异步请求接口,轻松解决并发问题

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 图形编辑器开发:实现自定义规则输入框组件

下一篇: 前端项目重构的深度思考和复盘

标签:
  • 热门焦点
  • 俄罗斯:将审查iPhone等外国公司设备 保数据安全

    iPhone和特斯拉都属于在各自领域领头羊的品牌,推出的产品也也都是数一数二的,但对于一些国家而言,它们的产品可靠性和安全性还是在限制范围内。近日,俄罗斯联邦通信、信息技术
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • 一加首款折叠屏!一加Open渲染图出炉:罕见单手可握小尺寸

    8月5日消息,此前就有爆料称,一加首款折叠屏手机将会在第三季度上市,如今随着时间临近,新机的各种消息也开始浮出水面。据悉,这款新机将会被命名为&ldquo;On
  • 不容错过的MSBuild技巧,必备用法详解和实践指南

    一、MSBuild简介MSBuild是一种基于XML的构建引擎,用于在.NET Framework和.NET Core应用程序中自动化构建过程。它是Visual Studio的构建引擎,可在命令行或其他构建工具中使用
  • 分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS网站旨在为全球Office用户提供丰富的高品质原创PPT模板、实用文档、数据图表及个性化定制服务。优点:OfficePLUS是微软官方网站,囊括PPT模板、Word模
  • 之家push系统迭代之路

    前言在这个信息爆炸的互联网时代,能够及时准确获取信息是当今社会要解决的关键问题之一。随着之家用户体量和内容规模的不断增大,传统的靠"主动拉"获取信息的方式已不能满足用
  • 重估百度丨“晚熟”的百度云,能等到春天吗?

    &copy;自象限原创作者|程心排版|王喻可2016年7月13日,百度云计算战略发布会在北京举行,宣告着百度智能云的正式启程。彼时的会场座无虚席,甚至排队排到了门外,在场的所有人几乎都
  • 年轻人的“职场羞耻感”,无处不在

    作者:冯晓亭 陶 淘 李 欣 张 琳 马舒叶来源:燃次元&ldquo;人在职场,应该选择什么样的着装?&rdquo;近日,在网络上,一个与着装相关的帖子引发关注,在该帖子里,一位在高级写字楼亚洲金
  • iQOO Neo8 Pro抢先上架:首发天玑9200+ 安卓性能之王

    经过了一段时间的密集爆料,昨日iQOO官方如期对外宣布:将于5月23日推出全新的iQOO Neo8系列新品,官方称这是一款拥有旗舰级性能调校的作品。随着发布时
Top