【总结版】Springboot下延迟返回小工具

本文介绍了如何在Springboot项目中利用DeferredResult处理同步异步请求,提高性能并实现解耦。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Springboot + DeferredResult

说明: DeferredResult内容网上资料很多,自己也可看源码分析,本篇仅记录个人在项目中使用DeferredResult的心得体会,以及它基本的使用情况。

博客内容精选:
1、Servlet请求体重复读&修改新姿势
2、根据请求获取后端接口详情
3、封装Springboot项目的starter-sdk新方式
4、Springboot全局处理完整版
5、itextpdf读取文本时上下行位置错乱
6、JAVA读取PDF表格内容
7、JAVA读取PDF出现内容错乱

背景: 项目需求需要接口同时支持同步、异步方式,且项目因模块化拆分,API接口端和实际处理端分开部署,中间以MQ作为传输通道,如下面所示:
在这里插入图片描述

因处理流程不在一个进程内,且同时支持同/异步,如果采用传统方法,适配代码及逻辑较为繁琐,代码也不美观,可读性较差。采用DeferredResult工具后,所有场景都可适配,仅简单判断分情况封装即可。

1、全局封装每个请求的DeferredResult

DeferredResult<ResponseEntity<Result>> deferredResult = new DeferredResult<>(60000, () -> {
   // Result为个人定制类,按需自定义
   Result timeoutRes = Result.newErrorResponse(requestId, "execute millisecond takes more than 60s");
   // 超时状态码及请求体设置
   return ResponseEntity.status(HttpStatus.SC_REQUEST_TIMEOUT).body(timeoutRes);
});

2、异步请求直接确认

deferredResult.setResult(ResponseEntity.ok(Result.newOkResponse(requestId, "")));

3、同步请求需要在内存中记录,以requestId为key,deferredResult为value

// Map缓存
HTTP_DEFERRED_RESULTS.put(requestId, deferredResult);

// 同步处理
try {
	//此块为与其他模块对接内容,对接端默认是IO耗时操作,需要较多资源,此处直接封装后推送至队列即可
	
    // 发送至队列后设置超时回调任务,推送失败不存在超时场景
    deferredResult.onTimeout(() -> {
    	//因有内存记录,业务超时后清除所作必须存在,否则造成内除泄露,超时响应体前部已设置
    	HTTP_DEFERRED_RESULTS.remove(requestId);
    });
} catch (ConvertException e) {
    // 中间件连接失败清理内存记录,避免内存泄露
    HTTP_DEFERRED_RESULTS.remove(requestId);
    deferredResult.setResult(ResponseEntity.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).body(Result.newErrorResponse(requestId, e.getMessage())));
}

总结:DeferredResult帮助项目应对多种涉及需求,并提供友好API实现对各种场景响应的封装。同步方式中仅需记录请求对应的DeferredResult,后续不再占用线程资源,极高提升了系统的吞吐量,不会被后端长IO操作拖累,是解耦优化的利器。有需要根据自身项目调整,可做备用小知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值