电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

SpringBoot的DeferredResult案例:DeferredResult的超時處理方式

瀏覽:92日期:2023-03-29 14:50:45

DeferredResult的超時處理,采用委托機(jī)制,也就是在實(shí)例DeferredResult時給予一個超時時長(毫秒),同時在onTimeout中委托(傳入)一個新的處理線程(我們可以認(rèn)為是超時線程);當(dāng)超時時間到來,DeferredResult啟動超時線程,超時線程處理業(yè)務(wù),封裝返回數(shù)據(jù),給DeferredResult賦值(正確返回的或錯誤返回的)。

這個實(shí)例可以對上一個實(shí)例的代碼稍作改動即可。

一、增加超時處理任務(wù)TimeOutWork

package com.example; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.context.request.async.DeferredResult; public class TimeOutWork implements Runnable{ private final Logger logger = LoggerFactory.getLogger(this.getClass()); private DeferredResult<ResponseMsg<String>> deferredResult; public TimeOutWork(DeferredResult<ResponseMsg<String>> deferredResult) { this.deferredResult = deferredResult; } @Override public void run() { logger.debug('我超時啦!'); ResponseMsg<String> msg = new ResponseMsg<String>(); msg.fail('我超時啦!'); //deferredResult.setResult(msg); deferredResult.setErrorResult(msg); }}二、DeferredResult請求中注冊超時任務(wù)處理

修改第一個請求,修改了兩處,請自己比較

package com.example; import java.util.HashMap;import java.util.Map; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.context.request.async.DeferredResult; @RestController@RequestMapping('/api')public class DeferredRestController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Map<Integer, DeferredResult<ResponseMsg<String>>> responseBodyMap = new HashMap<Integer, DeferredResult<ResponseMsg<String>>>(); private final Map<Integer, RequestMsg> requestBodyMap = new HashMap<Integer, RequestMsg>(); /** * 第一個請求 * * @param req * @return */ @RequestMapping('/request1') @ResponseBody public DeferredResult<ResponseMsg<String>> request1(RequestMsg req) { logger.debug('request1:請求參數(shù){}', req.getParam()); DeferredResult<ResponseMsg<String>> result =new DeferredResult<ResponseMsg<String>>(10000l);//10秒 result.onTimeout(new TimeOutWork(result));//超時任務(wù) requestBodyMap.put(1, req);// 把請求放到第一個請求map中 responseBodyMap.put(1, result);// 把請求響應(yīng)的DeferredResult實(shí)體放到第一個響應(yīng)map中 return result; } /** * 第二個請求 * * @param req * @return */ @RequestMapping('/request2') @ResponseBody public DeferredResult<ResponseMsg<String>> request2(RequestMsg req) { logger.debug('request2:請求參數(shù){}', req.getParam()); DeferredResult<ResponseMsg<String>> result = new DeferredResult<ResponseMsg<String>>(); requestBodyMap.put(2, req);// 把請求放到第二個請求map中 responseBodyMap.put(2, result);// 把請求響應(yīng)的DeferredResult實(shí)體放到第二個響應(yīng)map中 return result; } /** * 第三個請求 * * @param req * @return */ @RequestMapping('/request3') @ResponseBody public DeferredResult<ResponseMsg<String>> request3(RequestMsg req) { logger.debug('request3:請求參數(shù){}', req.getParam()); DeferredResult<ResponseMsg<String>> result = new DeferredResult<ResponseMsg<String>>(); requestBodyMap.put(3, req);// 把請求放到第三個請求map中 responseBodyMap.put(3, result);// 把請求響應(yīng)的DeferredResult實(shí)體放到第三個響應(yīng)map中 return result; } /** * 控制第x個請求執(zhí)行返回操作,同時自己也返回同樣的值 * * @param x * @return */ @RequestMapping(value = '/requestXReturn', method = RequestMethod.POST) @ResponseBody public ResponseMsg<String> request1Return(Integer x) { ResponseMsg<String> msg = new ResponseMsg<String>(); logger.debug('requestXReturn--1:請求參數(shù){}', x); DeferredResult<ResponseMsg<String>> result = responseBodyMap.get(x); if (result == null) { msg.fail('??!請求已經(jīng)釋放'); return msg; } String resultStr = 'result' + x.toString() + '. Received:' + requestBodyMap.get(x).getParam(); msg.success('成功', resultStr); result.setResult(msg);// 設(shè)置DeferredResult的結(jié)果值,設(shè)置之后,它對應(yīng)的請求進(jìn)行返回處理 responseBodyMap.remove(x);// 返回map刪除 logger.debug('requestXReturn--2:請求參數(shù){}', x); logger.debug('requestXReturn--3:返回參數(shù){}', msg); return msg; }}三、修改頁面index.html

<script th:src='http://www.hdgsjgj.cn/bcjs/@{jquery-1.12.4.min.js}' type='text/javascript'></script> <script th:inline='javascript'> function button1RequestClick(){ var param=$('#request1RequestId').val(); $.ajax({ type:’post’, url:’/api/request1’, dataType : ’json’, data : { ’param’ : param }, success : function(data) { console.log(data); if (data.status==0){ $('#request1ResultId').val(data.data); } else { $('#request1ResultId').val(data.msg); } }, error : function(data) { console.log('button1RequestClick---error'); console.log(data); //alert('錯誤消息:' + data); } }); };

前后的代碼都省略了,其實(shí)僅僅修改了

if (data.status==0){ $('#request1ResultId').val(data.data);} else { $('#request1ResultId').val(data.msg);}四、小結(jié)

DeferredResult的超時處理比較簡單,定義時長及注冊一個處理Runnable實(shí)例即可。對于setResult、setErrorResult還需要繼續(xù)研究。

1、setResult

SpringBoot的DeferredResult案例:DeferredResult的超時處理方式

2、setErrorResult

SpringBoot的DeferredResult案例:DeferredResult的超時處理方式

3、isSetOrExpired

SpringBoot的DeferredResult案例:DeferredResult的超時處理方式

補(bǔ)充:解決了DeferredResult請求長時間占用數(shù)據(jù)庫連接的問題

最近看了看開源項(xiàng)目appllo配置中心的源碼,發(fā)現(xiàn)一個很有意思的東東:

(1)原理:由于使用了DeferredResult,根據(jù)Spring DispatcherServlet的默認(rèn)邏輯,數(shù)據(jù)庫連接只有在異步請求真正返回給客戶端的時候才會釋放回連接池

(2)應(yīng)用場景:長連接時間很長,對于大部分請求可能都要數(shù)小時以上才會返回。在這么長的一段時間內(nèi)一直占用著數(shù)據(jù)庫連接是不合理的

長連接場景解決:

@Componentpublic class EntityManagerUtil extends EntityManagerFactoryAccessor { private static final Logger logger = LoggerFactory.getLogger(EntityManagerUtil.class); /** * close the entity manager. * Use it with caution! This is only intended for use with async request, which * Spring won’t close the entity manager until the async request is finished. */ public void closeEntityManager() { EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(getEntityManagerFactory()); if (emHolder == null) { return; } logger.debug('Closing JPA EntityManager in EntityManagerUtil'); EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager()); }}

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。如有錯誤或未考慮完全的地方,望不吝賜教。

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 锂电池生产厂家-电动自行车航模无人机锂电池定制-世豹新能源 | 河南凯邦机械制造有限公司 | 房间温控器|LonWorks|海思| 深圳快餐店设计-餐饮设计公司-餐饮空间品牌全案设计-深圳市勤蜂装饰工程 | 龙门加工中心-数控龙门加工中心厂家价格-山东海特数控机床有限公司_龙门加工中心-数控龙门加工中心厂家价格-山东海特数控机床有限公司 | 自清洗过滤器-全自动自清洗过反冲洗过滤器 - 中乂(北京)科技有限公司 | 铝合金风口-玻璃钢轴流风机-玻璃钢屋顶风机-德州东润空调设备有限公司 | 微水泥_硅藻泥_艺术涂料_艺术漆_艺术漆加盟-青岛泥之韵环保壁材 武汉EPS线条_EPS装饰线条_EPS构件_湖北博欧EPS线条厂家 | 1000帧高速摄像机|工业高速相机厂家|科天健光电技术 | 粉末冶金注射成型厂家|MIM厂家|粉末冶金齿轮|MIM零件-深圳市新泰兴精密科技 | 路斯特伺服驱动器维修,伦茨伺服驱动器维修|万骏自动化百科 | 办公室家具_板式办公家具定制厂家-FMARTS福玛仕办公家具 | 上海阳光泵业制造有限公司 -【官方网站】 | 非小号行情 - 专业的区块链、数字藏品行情APP、金色财经官网 | 高博医疗集团上海阿特蒙医院 | 合肥宠物店装修_合肥宠物美容院装修_合肥宠物医院设计装修公司-安徽盛世和居装饰 | 铁素体测量仪/检测仪/铁素体含量测试仪-苏州圣光仪器有限公司 | 美国PARKER齿轮泵,美国PARKER柱塞泵,美国PARKER叶片泵,美国PARKER电磁阀,美国PARKER比例阀-上海维特锐实业发展有限公司二部 | 视觉检测设备_自动化检测设备_CCD视觉检测机_外观缺陷检测-瑞智光电 | 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 捆扎机_气动捆扎机_钢带捆扎机-沈阳海鹞气动钢带捆扎机公司 | 广东机电安装工程_中央空调工程_东莞装饰装修-广东粤标建设有限公司 | 油罐车_加油机_加油卷盘_加油机卷盘_罐车人孔盖_各类球阀_海底阀等车用配件厂家-湖北华特专用设备有限公司 | 快干水泥|桥梁伸缩缝止水胶|伸缩缝装置生产厂家-广东广航交通科技有限公司 | 净化车间_洁净厂房_净化公司_净化厂房_无尘室工程_洁净工程装修|改造|施工-深圳净化公司 | 防火门|抗爆门|超大门|医疗门|隔声门-上海加汇门业生产厂家 | 四川实木门_成都实木门 - 蓬溪聚成门业有限公司 | 上海单片机培训|重庆曙海培训分支机构—CortexM3+uC/OS培训班,北京linux培训,Windows驱动开发培训|上海IC版图设计,西安linux培训,北京汽车电子EMC培训,ARM培训,MTK培训,Android培训 | 全自动五线打端沾锡机,全自动裁线剥皮双头沾锡机,全自动尼龙扎带机-东莞市海文能机械设备有限公司 | RV减速机-蜗轮蜗杆减速机-洗车机减速机-减速机厂家-艾思捷 | 球磨机,节能球磨机价格,水泥球磨机厂家,粉煤灰球磨机-吉宏机械制造有限公司 | 软膜天花_软膜灯箱_首选乐创品牌_一站式天花软膜材料供应商! | 好看的韩国漫画_韩漫在线免费阅读-汗汗漫画| DDoS安全防护官网-领先的DDoS安全防护服务商 | 123悬赏网_发布悬赏任务_广告任务平台 | 低气压试验箱_高低温低气压试验箱_低气压实验箱 |林频试验设备品牌 | 包装设计公司,产品包装设计|包装制作,包装盒定制厂家-汇包装【官方网站】 | 植筋胶-粘钢胶-碳纤维布-碳纤维板-环氧砂浆-加固材料生产厂家-上海巧力建筑科技有限公司 | 智能监控-安防监控-监控系统安装-弱电工程公司_成都万全电子 | 全自动贴标机-套标机-工业热风机-不干胶贴标机-上海厚冉机械 | 泰安塞纳春天装饰公司【网站】 |