高并发下的耗时操作

官方文档中说DeferredResult和Callable都是为了异步生成返回值提供基本的支持。简单来说就是一个请求进来,如果你使用了DeferredResult或者Callable,在没有得到返回数据之前,DispatcherServlet和所有Filter就会退出Servlet容器线程,但响应保持打开状态,一旦返回数据有了,这个DispatcherServlet就会被再次调用并且处理,以异步产生的方式,向请求端返回值。

这么做的好处就是请求不会长时间占用服务连接池,提高服务器的吞吐量。

高并发下,就是请求在一个时间点比较多时,很多写的请求打过来时,你的服务器承受很大的压力,当你的一个请求处理时间长时,这些请求将会把你的服务器线程耗尽,即你的主线程池里的线程将不会再有空闲状态的,再打过来的请求,将会是502了。

请求流程图

http1 http2 http3

thread1 thread2 thread3

解决方案

使用DeferredResult来实现异步的操作,当一个请求打过来时,先把它放到一个队列时,然后在后台有一个订阅者,有相关主题的消息发过来时,这个订阅者就去消费它,这一步可以是分布式的,比如一个秒杀场景,当N多的请求打过来时,有一些请求命中后,它们进行写操作,这时写操作压力很大,1个请求可以要处理3秒,对于高并发场景这是不能容许的,因为你这样占用的服务器线程资源太长了,很快你的服务器就没有可用的线程资源了,这时就可以用到DeferredResult这处理。

代码实现

建立订单的接口,只负责简单的校验和事件的发布

/**

* 异步建立高并发的订单.

*

* @return

*/

@GetMapping("/create-order")

public DeferredResult createOrder() {

DeferredResult deferredResult = new DeferredResult<>((long) 3000, "error order");

logger.info("发布建立订单的事件");

applicationEventPublisher.publishEvent(deferredResult);

return deferredResult;

}

异步的订单处理核心逻辑,也是耗时的操作

@Component

@EnableAsync

public class OrderListener {

static Logger logger = LoggerFactory.getLogger(OrderListener.class);

/**

* 事实上它是一个订单队列的消费者,在后台写订单,本例使用简单的事件监听器实现异步处理的功能.

*

* @return

*/

@EventListener

@Async

public String processOrder(DeferredResult deferredResult) throws InterruptedException {

logger.info("处理订单并返回到对应的Http上下文");

String order = UUID.randomUUID().toString();

Thread.sleep(2000);//假设处理数据需要5秒,前端需要阻塞5秒,但http主线程已经释放了,比较适合IO密集型场合

//当设置之后,create-order将成功响应

deferredResult.setResult(order);

return order;

}

}

测试结果

当请求/create-order后,服务器在处理2秒后,返回结果,而spring后台真正做的是,线程1在事件发布后,它成为空闲状态,其它请求可以复用它,当processOrder后台处理结果后,spring又会用线程池中拿一个新的线程处理剩下的逻辑!

java耗时操作阻塞_springboot~高并发下耗时操作的实现相关推荐

  1. java耗时操作阻塞_spring boot高并发下耗时操作的实现方法

    高并发下的耗时操作 高并发下,就是请求在一个时间点比较多时,很多写的请求打过来时,你的服务器承受很大的压力,当你的一个请求处理时间长时,这些请求将会把你的服务器线程耗尽,即你的主线程池里的线程将不会再 ...

  2. springboot高并发下耗时操作的实现,我先收藏为敬

    什么是 Arthas? Arthas 是一款开源在线诊断工具,采用命令行交互模式,支持 web 端在线诊断,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断.这是一款开源一年多 G ...

  3. java如何保证数据安全_java高并发下怎么保障数据安全?有哪些办法?

    近些年科技发展水平越来越快速了,这也促使了大家对于新兴软件的学习.尤其是对于java的渴求更是明显,这也进一步说明了java功能的强大.今天就来为大家介绍一下java高并发下怎么保障数据安全以及有哪些 ...

  4. JAVA random 缺陷_Random在高并发下的缺陷以及JUC对其的优化

    Random可以说是每个开发都知道,而且都用的很6的类,如果你说,你没有用过Random,也不知道Random是什么鬼,那么你也不会来到这个技术类型的社区,也看不到我的博客了.但并不是每个人都知道Ra ...

  5. java 转账 锁_java 关于高并发下的银行转账问题

    在转账操作中,一致性必须要保证的,转账的前后,各个账户的金额必须符合算术一致性 如何保证一致性? 引入事务机制是肯定的,但是这就够了么,下面我们对其进行测试 场景: 小明账户中有10000元,小强账户 ...

  6. java 怎么保证余额_高并发下怎么做余额扣减?

    余额操作在大多数系统都是不可缺少和不允许出现问题的 如何修改余额 , 这个问题可能在实际项目中 没那么简单; 如何修改余额 假设一个用户数据 : id⇒12 | user_name⇒放放 | fee⇒ ...

  7. ajax调用接口很慢,nodejs 请求接口在高并发下耗时很大,而单个请求非常快

    情况: request.js 库请求接口, express.js 做 server ,实现了 curl http://localhost:8080/proxy-api 本地一个地址,在 router ...

  8. Day783.网络通信优化之I/O模型:如何解决高并发下I/O瓶颈 -Java 性能调优实战

    网络通信优化之I/O模型:如何解决高并发下I/O瓶颈 Hi,我是阿昌,今天学习记录的是关于网络通信优化之I/O模型:如何解决高并发下I/O瓶颈. 提到 Java I/O,相信你一定不陌生. 可能使用 ...

  9. java list 转 map_高并发下的Java数据结构(List、Set、Map、Queue)

    由于并行程序与串行程序的不同特点,适用于串行程序的一些数据结构可能无法直接在并发环境下正常工作,这是因为这些数据结构不是线程安全的.本节将着重介绍一些可以用于多线程环境的数据结构,如并发List.并发 ...

最新文章

  1. PHP HashTable总结
  2. noip提高组2000 乘积最大
  3. Vue 封装面包屑 (即粘即用)
  4. php 数组 键值 初始化,PHP 自定义键值数组
  5. SQL Server 高可用性(一)AlwaysOn 技术
  6. android打包签名
  7. KNN算法虹膜图片识别(源码)
  8. Redis Command
  9. java--GUI窗口可视化编程1
  10. 教师录微课及剪辑软件推荐
  11. 渗透测试PTES标准流程(超详细)
  12. HTML+CSS+JS制作爱心表白代码 520情人节源码HTML 七夕情人节表白代码制作 生日祝福代码
  13. Excel双样本T检验之异方差检验
  14. 小皮phpstudy无法启动mysql的解决方法
  15. java蘑菇岛种子_我的世界:以2002年2月12日为种子代码,居然是蘑菇岛神级种子!...
  16. vue 搜索框添加历史搜索记录
  17. 项目简要建设情况汇报材料报告
  18. 20世纪十大哲学问题
  19. 微生物和微生物组的定义以及发展史
  20. Google Android软件架构

热门文章

  1. ios测试宏指令出错:“Expected identefier”
  2. 告别2008 明天2009
  3. python把dict转为dataframe,将python OrderedDict转换为datafram
  4. yolov3代码详解_代码资料
  5. phantomjs linux 中文不显示,linux 安装phantomJs 用于截图,处理中文乱码,和样式问题...
  6. php curl向另一个页面post,一个PHP CURL的POST提交遇到的问题
  7. linux php常用命令,php调用Linux系统常用命令
  8. 计算机专业报专转本可以志愿,2019年专转本志愿怎么填?专家透露报考窍门
  9. db2 最近三个月_昙花一现,PA、PC月跌1800,通用料一蹶不振,救不起的塑市!
  10. linux内核全局变量重定位,关于可重定位文件中全局变量的一个重定位疑惑,借各位牛刀一用^...