av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

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

SpringBoot的DeferredResult案例:DeferredResult的超時(shí)處理方式

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

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

這個(gè)實(shí)例可以對(duì)上一個(gè)實(shí)例的代碼稍作改動(dòng)即可。

一、增加超時(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('我超時(shí)啦!'); ResponseMsg<String> msg = new ResponseMsg<String>(); msg.fail('我超時(shí)啦!'); //deferredResult.setResult(msg); deferredResult.setErrorResult(msg); }}二、DeferredResult請(qǐng)求中注冊(cè)超時(shí)任務(wù)處理

修改第一個(gè)請(qǐng)求,修改了兩處,請(qǐng)自己比較

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>(); /** * 第一個(gè)請(qǐng)求 * * @param req * @return */ @RequestMapping('/request1') @ResponseBody public DeferredResult<ResponseMsg<String>> request1(RequestMsg req) { logger.debug('request1:請(qǐng)求參數(shù){}', req.getParam()); DeferredResult<ResponseMsg<String>> result =new DeferredResult<ResponseMsg<String>>(10000l);//10秒 result.onTimeout(new TimeOutWork(result));//超時(shí)任務(wù) requestBodyMap.put(1, req);// 把請(qǐng)求放到第一個(gè)請(qǐng)求map中 responseBodyMap.put(1, result);// 把請(qǐng)求響應(yīng)的DeferredResult實(shí)體放到第一個(gè)響應(yīng)map中 return result; } /** * 第二個(gè)請(qǐng)求 * * @param req * @return */ @RequestMapping('/request2') @ResponseBody public DeferredResult<ResponseMsg<String>> request2(RequestMsg req) { logger.debug('request2:請(qǐng)求參數(shù){}', req.getParam()); DeferredResult<ResponseMsg<String>> result = new DeferredResult<ResponseMsg<String>>(); requestBodyMap.put(2, req);// 把請(qǐng)求放到第二個(gè)請(qǐng)求map中 responseBodyMap.put(2, result);// 把請(qǐng)求響應(yīng)的DeferredResult實(shí)體放到第二個(gè)響應(yīng)map中 return result; } /** * 第三個(gè)請(qǐng)求 * * @param req * @return */ @RequestMapping('/request3') @ResponseBody public DeferredResult<ResponseMsg<String>> request3(RequestMsg req) { logger.debug('request3:請(qǐng)求參數(shù){}', req.getParam()); DeferredResult<ResponseMsg<String>> result = new DeferredResult<ResponseMsg<String>>(); requestBodyMap.put(3, req);// 把請(qǐng)求放到第三個(gè)請(qǐng)求map中 responseBodyMap.put(3, result);// 把請(qǐng)求響應(yīng)的DeferredResult實(shí)體放到第三個(gè)響應(yīng)map中 return result; } /** * 控制第x個(gè)請(qǐng)求執(zhí)行返回操作,同時(shí)自己也返回同樣的值 * * @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:請(qǐng)求參數(shù){}', x); DeferredResult<ResponseMsg<String>> result = responseBodyMap.get(x); if (result == null) { msg.fail('??!請(qǐng)求已經(jīng)釋放'); return msg; } String resultStr = 'result' + x.toString() + '. Received:' + requestBodyMap.get(x).getParam(); msg.success('成功', resultStr); result.setResult(msg);// 設(shè)置DeferredResult的結(jié)果值,設(shè)置之后,它對(duì)應(yīng)的請(qǐng)求進(jìn)行返回處理 responseBodyMap.remove(x);// 返回map刪除 logger.debug('requestXReturn--2:請(qǐng)求參數(shù){}', x); logger.debug('requestXReturn--3:返回參數(shù){}', msg); return msg; }}三、修改頁(yè)面index.html

<script th:src='http://www.4tl426be.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('錯(cuò)誤消息:' + data); } }); };

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

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

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

1、setResult

SpringBoot的DeferredResult案例:DeferredResult的超時(shí)處理方式

2、setErrorResult

SpringBoot的DeferredResult案例:DeferredResult的超時(shí)處理方式

3、isSetOrExpired

SpringBoot的DeferredResult案例:DeferredResult的超時(shí)處理方式

補(bǔ)充:解決了DeferredResult請(qǐng)求長(zhǎng)時(shí)間占用數(shù)據(jù)庫(kù)連接的問(wèn)題

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

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

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

長(zhǎng)連接場(chǎng)景解決:

@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()); }}

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

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 久久久久国产精品午夜一区 | 精品一区二区三区视频在线观看 | 亚洲一区 中文字幕 | 欧美国产精品一区二区三区 | 国产区精品视频 | heyzo在线| 欧美日产国产成人免费图片 | 成人性视频免费网站 | 91免费在线视频 | 亚洲天堂一区 | 龙珠z在线观看 | 国产视频中文字幕在线观看 | 夜夜av | 欧美日韩视频 | 午夜播放器在线观看 | 黄色大片观看 | 日本特黄a级高清免费大片 成年人黄色小视频 | 精品国产乱码久久久久久a丨 | 激情小视频 | 久久久久久久国产精品 | 欧美视频1区 | 久久99精品久久久久 | xxxxx免费视频 | 欧美在线观看一区 | 国产视频观看 | 久久精品一 | 久久草在线视频 | 亚洲精品电影在线观看 | 最近日韩中文字幕 | 欧美在线视频一区二区 | 99精品欧美 | jizz在线免费观看 | 在线观看午夜视频 | 午夜精品久久久久久久久久久久久 | 色综合美女 | 成人亚洲视频 | 成人精品国产免费网站 | 亚洲精品乱码久久久久久按摩观 | 成人在线视频网 | 91精品久久久久久久久久 | 宅女噜噜66国产精品观看免费 |