调用接口处理时间过长,前端访问超时解决方案
2019獨角獸企業重金招聘Python工程師標準>>>
????在項目中會遇到這樣的情況,由于后臺需要執行、計算一段時間(如計算積分、自動排課等)。這時前臺請求一段時間后,得不到返回結果就會發生請求超時。
????拿自動排課來說,如果一個學校上百個班級,執行一次排課可能需要1-2分鐘甚至更長時間,那么會造成前臺訪問接口超時(當然也可以延長超時時間實現)。
解決方案:
????考慮改造為輪詢查詢程序執行結果。
????1. 后臺改造:
????????將自動排課功能的接口分為兩個:
????????????①創建線程執行自動排課
????????????②提供接口查詢排課結果
????????對原有的方法進行改造:原有的方法,方法執行完成后才會返回執行結果。時間過長,考慮將原方法改造為線程執行,這樣一旦線程開始執行,就可以返回結果。
?
????????改造方法:
- 自動排課功能所在的service類實現Runnable接口,將自動排課的實現邏輯寫在run方法中。
- 編寫方法①創建并執行線程,執行run方法。
- Controller層調用方法①實現自動排課功能。
- 對于自動排課結果,可以放在redis中,接口①實時更新自動排課的狀態(成功或者失敗),可以通過接口②每間隔一段時間查詢自動排課的結果。
????????
????????代碼示例:
Controller層
@Controller public class Controller{@Autowired//自動注入排課功能所在的serviceprivate CourseTableService courseTableService; @RequestMapping(value = "/arrange/{id}")@ResponseBodypublic ResponseMessage arrange(@PathVariable String id) {return courseTableService.arrange(id); //自動排課}@RequestMapping(value = "/arrangeResult/{id}")@ResponseBodypublic Map<String,Object> arrangeResult(@PathVariable String id) {//查詢自動排課結果,并返回} }Service層
@Service @Transactional(readOnly = true) public class CourseTableService implements Runnable { //實現Runnable接口@Autowiredprivate ThreadPoolTaskExecutor taskExecutor; //線程池 //自動paikepublic ResponseMessage arrange(String scheduleId) {this.scheduleId=scheduleId; //設置run方法中需要用的參數taskExecutor.execute(this); //執行線程return ResponseMessage.ok(); //返回線程執行結果}//自動排課,線程public void run(){ //排課邏輯代碼String scheId=this.scheduleId; //使用接收的參數} }?
????2. 前端大致分兩次請求后臺接口:
????第一次請求接口自動排課(線程或者mQ執行),這樣在啟動自動排課的時候就返回請求結果,告知用戶正在進行排課。
????然后輪詢調用第二接口,每隔幾秒鐘就去查詢排課的結果。如果返回的狀態為0代表排課成功,提示用戶;如果返回的狀態為1達標排課失敗,提示失敗原因;如果返回的狀態為2代表排課正在執行中,繼續輪詢訪問查詢排課結果的接口。
????主要代碼示例:
var intervalFlag=true; //是否執行輪詢的標志 //_post2是封裝的ajax請求, $._post2('/arrange/' + _id, {}, function(res) { var interVal;//調用接口,查詢自動排課結果,加上這個是為了用戶點擊后立馬訪問,ajax同步訪問,//因為這次的查詢結果決定了,是否執行輪詢。getProgress(_id, interVal); if(intervalFlag){//第一次查詢結果表明排課還在進行中,才會執行輪詢。//如果第一次已經返回結果表示程序執行完成,就不需要輪詢訪問排課結果了。interval(_id); } });// 進度查詢 function getProgress(_id, interVal) {$._post2('/arrangeResult/' + _id, {}, function(res) {if (res.arrangeStatus == 0) {//排課成功clearInterval(interVal); //清空輪詢intervalFlag=false; //設置為不執行輪詢}else if(res.arrangeStatus==1){//排課失敗clearInterval(interVal);intervalFlag=false;}else if(res.arrangeStatus==2){//排課進行中,什么都不做}}); }// 隔兩秒訪問 function interval(_id) {var pro;// 定時器var interVal;interVal = setInterval(function() {// 獲取返回對象pro = getProgress(_id, interVal);}, 2000); }?
轉載于:https://my.oschina.net/u/3706132/blog/1550617
總結
以上是生活随笔為你收集整理的调用接口处理时间过长,前端访问超时解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大家好,给大家介绍一下,这是我的智能伙伴
- 下一篇: 百度怎么发表文章(百度产品大全)