非同步HTTP請求

2021-09-18 06:15:22 字數 1794 閱讀 1976

a專案中遇到乙個匯出功能,中間有呼叫到b專案檢視,b專案提供的檢視在業務高發期極度緩慢,正常執行時間為20-50ms,但是偶爾會慢到七八分鐘,最長時會阻塞到兩三個小時.故,在多使用者同時進行匯出時,會佔滿伺服器連線,導致新請求阻塞,專案卡死.跟b系統開發反饋會得知,該檢視已經優化多次,繼續優化空間不大.同時,資料實時性要求較高,無法新增redis快取.所以提出解決方案如下:

1.為該請求加上超時時間

2.進行http非同步請求

3.限制單個使用者同時發起多個請求

1.首先要新增乙個執行緒池來執行我們的業務**,從而空出伺服器執行緒以便接受其他請求.

因為我們專案框架是springmvc,所以我們要用spring來建立乙個執行緒池

2.配置spring可以處理非同步的http請求

接著給所有的servlet和filter都加上

true
注意的是,所有的都要加,剛開始只給dispatcherservlet加了,果然有問題.

2.2:controller中返回特定的結果

2.2.1:callable介面

返回乙個callable介面,spring會自己幫我們用執行緒池啟動新的執行緒去執行,這裡會使用預設的執行緒池,有多少請求進來會開多少執行緒,所以我們需要配置自己需要的執行緒池來限制.

需要在springmvc的配置裡加上

這樣可以自定義超時時間和執行業務**的執行緒池.

2.2.2 deferredresult

通過返回這個引數,也可以起到非同步的作用,這樣可以更靈活的處理業務.

deferredresultdeferredresult = new deferredresult(800_000l);

deferredresult.ontimeout(() ->

deferredresult.setresult("fail")

);try else

} catch (exception e) finally

});} catch (rejectedexecutionexception e)

return deferredresult;

首先,我們新建乙個deferredresult,建構函式裡可以設定超時時間,到達這個時間後會自動觸發timeout方法,但是需要注意的是這裡的超時並不會將業務執行緒終止.

那麼,我們應該如何終止業務執行緒呢:

錯誤嘗試:

首先想到的是用callable介面去處理,async.submit().get()來獲取結果

這裡有兩個問題,

一是主線程中使用get會將主線程卡死,無法起到非同步處理的作用,所以我新建裡監控執行緒,在監控執行緒中get,防止主線程鎖死.

二是get後如何終止執行緒,可以看到的是有shutdown(),shutdonwnnow(),interrupt()等方法,但是不幸的是,這幾個方法都無法保證可以真正的停止執行緒,不像linux裡面kill -9,想想也是有道理的,別的執行緒怎麼能處理業務執行緒的狀態呢,萬一資料不一致怎麼辦.(要麼處於sleep(),wait()狀態可以丟擲異常,要麼自己的**裡判斷isinterrupt 來確定執行緒是否繼續執行)

所以,我在mybatis中設定了超時時間,當sql查詢過慢時終止查詢.(socket層,statement層,transaction事務層)這裡我設定在statement層.()

3,單個使用者發起請求的限制

在redis中用使用者id為key去做記錄,進行業務操作前先判斷redis中該key是否存在,這裡要注意報錯刪除key,超時刪除key等

http 同步非同步請求

在使用者互動模式下,當你改變表單中某個元件的值時,譬如你填寫名字 修改性別 選擇愛好的時候,瀏覽器和服 務器至今沒有發生任何互動,只有當你點選submit的時候,瀏覽器才會把你的引數,也就是form表單中各元件的值,打包成乙個http請求中發給伺服器。而且,一旦傳送出去,整個頁面就會全部重新整理,重...

非同步與同步http請求

非同步請求 nsmutabledata buf nsmutabledata alloc initwithlength 0 nsurlconnection connection nsurlconnection alloc initwithrequest req delegate self 收到響應時,...

php curl 非同步併發請求http

先來看下同步的 以及請求時間。start time date h i sa for i 0 i 100 i function geturl url function gettitle output end time date h i sa echo 開始時間是 start time echo 結束時...