Spring基础学习-SpringMVC异步处理模式分析(DeferredResult/SseEmitter等)

本文详细介绍了SpringMVC中异步处理的背景和方式,包括Callable、DeferredResult、SseEmitter和StreamingResponseBody的使用。通过实例展示了如何利用这些机制处理耗时操作,减少服务器连接占用,提高客户端体验。特别地, DeferredResult允许在其他线程中设置结果,而SseEmitter则用于流式传输多个结果。
摘要由CSDN通过智能技术生成

本文目录

1. 背景

Tomcat等应用服务器的连接线程池实际上是有限制的;每一个连接请求都会耗掉线程池的一个连接数;如果某些耗时很长的操作,如对大量数据的查询操作、调用外部系统提供的服务以及一些IO密集型操作等,会占用连接很长时间,这个时候这个连接就无法被释放而被其它请求重用。如果连接占用过多,服务器就很可能无法及时响应每个请求;极端情况下如果将线程池中的所有连接耗尽,服务器将长时间无法向外提供服务!

在常规场景中,客户端需要等待服务器处理完毕后返回才能继续进行其它操作,这个场景下每一步都是同步调用,如客户端调用Servlet后需要等待其处理返回,Servlet调用具体的Controller后也需要等待其返回。这种情况是在服务器端开发中最常见的场景,适合于服务器端处理时间不是很长的情况;默认情况下Spring的Controller提供的就是这样的服务。

当某项服务处理时间过长时,如邮件发送,需要调用到外部接口,处理时间不受调用方的控制,因此如果耗时过长会有两个比较严重的后果:一是如上文所说的会长时间的占用请求连接数,严重时有可能导致服务器失去响应; 二是客户端等待时间过长,导致前端应用的用户友好性下降,而且客户很有可能因为长时间得不到服务器响应而重复操作,从而加重服务器的负担,使得应用崩溃的机率变大!
为应对这种场景,一般会启用一个后台的线程池,处理请求的Controller会先提交一个耗时长操作如邮件发送到线程池中,然后立即返回到前台。因此处理响应的主线程耗时变短,客户感受到的就是在点击某个发送按钮后很快就得到服务器反馈结果,然后就放心的继续处理其它工作。实际上邮件发送这种事情延迟几秒对于客户来说根本感受不到。当然应用需要保证提交到线程池中的任务执行成功,或者是执行失败后在前端某个地方能够看到失败的具体情况。

这种场景在Spring中可使用TaskExecutor或者是Async来处理,关于它们的用法请参考:Spring基础学习-任务执行(TaskExecutor及Async)

通过以上两种场景,很容易就会想到,如果某个操作既耗时很长,客户端又必须要等待其返回才能进一步处理时,应该通过什么方式来处理?Servlet3.0中引入异步请求处理来处理这种场景,相应的,Spring在3.2版本中就引入相关机制来使用Servlet的该特性。

2. SpringMVC异步处理概述

为满足耗时任务占用应用服务器连接数,而客户端又必须等待这些耗时长任务返回才能处理下一步工作的场景,Spring引入了以下机制来处理:

  • 使用Callable或者DeferredResult当成Controller的返回值,能够处理异步返回单个结果的场景
  • 使用ResponseBodyEmitter/SseEmitter或者StreamingResponseBody来流式处理多个返回值
  • 在Controller中使用响应式客户端调用服务并返回响应式的数据对象

2.1 Callable

Callable直接使用在Controller中被RequestMapping所注解的方法上,做为其返回对象。
使用示例:

@RequestMapping("/testCallable")
public Callable<String> testCallable() {
    logger.info("Controller开始执行!");
    Callable<String> callable = () -> {
        Thread.sleep(5000);

        logger.info("实际工作执行完成!");

        return "succeed!";
    };
    logger.info("Controller执行结束!");
    return callable;
}

使用浏览器访问http://loca

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值