1.為什么用異步化處理
異步化的目的無(wú)非就是為了減少response響應(yīng)時(shí)間, 提高用戶體驗(yàn), 提高資源(CPU, IO)利用率.
同步請(qǐng)求示意圖

異步請(qǐng)求示意圖

這里假設(shè)function1和service1都是比較耗時(shí)的操作, 調(diào)用時(shí)間如下:
- function1 = 2s
- service1 = 3s
那么最后的結(jié)果如下:
- 同步請(qǐng)求的request等待時(shí)間 = 2s + 3s = 5s
- 異步請(qǐng)求, 由于是請(qǐng)求立馬得到相應(yīng)的, 時(shí)間消耗應(yīng)該在100ms之內(nèi).
- 后續(xù)的獲得結(jié)果()這個(gè)步驟不一定是每個(gè)場(chǎng)景都需要(就是需要的話, 這個(gè)步驟應(yīng)該也是一個(gè)很快的操作, 控制在1s之內(nèi))
結(jié)論: 用異步化處理可以減少RT(響應(yīng)時(shí)間), 優(yōu)化用戶體驗(yàn).
2.哪些場(chǎng)景比較適合用異步化來(lái)處理呢 ?
異步化處理有它的好處, 但不是所有的請(qǐng)求都適合用異步化.
異步化的缺點(diǎn):
- 用戶的交互次數(shù)可能會(huì)增加
- 編碼變得復(fù)雜(要考慮多線程問(wèn)題)
下面列舉一些比較適合用異步化來(lái)處理的場(chǎng)景.
2.1 弱依賴的事務(wù)
比如一條數(shù)據(jù)的修改, 需要發(fā)送通知.
這里的發(fā)送通知就是弱依賴的事務(wù)(一般來(lái)說(shuō)是這樣的), 那么這個(gè)發(fā)送通知就可以異步化.
2.2 長(zhǎng)事務(wù)
比如導(dǎo)入, 導(dǎo)出.
這是一個(gè)非常耗時(shí)的事務(wù), 有時(shí)候可能要幾分鐘甚至十幾分鐘的, 這樣的事務(wù)沒(méi)必要讓用戶一直等著.
直接提示一個(gè)"正在導(dǎo)入/正在導(dǎo)出", 然后后臺(tái)慢慢執(zhí)行就好了.
做的好一點(diǎn)的, 還可以監(jiān)控一下整個(gè)進(jìn)度, 在頁(yè)面上顯示出來(lái).
2.3 非業(yè)務(wù)功能
比如說(shuō)日志記錄, 性能測(cè)試等.
特別是這些操作還需要操作數(shù)據(jù)庫(kù), 或者有一些網(wǎng)絡(luò)請(qǐng)求的時(shí)候, 特別要注意異步化處理.
3.請(qǐng)求異步化處理要注意的問(wèn)題
先看一下tomcat內(nèi)部的Request請(qǐng)求流程:

注意上圖的1.3.1和1.3.2, tomcat會(huì)在一個(gè)請(qǐng)求結(jié)束之后, 清理session和cookie中的信息.
結(jié)論:
由于異步化必然會(huì)產(chǎn)生一個(gè)新的線程, 然后這個(gè)新的線程對(duì)于request, response相關(guān)的操作(主要是針對(duì)cookie和session)是不能進(jìn)行的, 因?yàn)閏ookie和session可能會(huì)被清除, request中的attribute估計(jì)也會(huì)被清理掉(待研究)
但是如果實(shí)在要依賴于request中的信息的話, 比如要獲取登錄用戶的一些信息(一般放在session或cookie中), 也可以提前把request中需要的信息copy一份出來(lái), 供異步線程使用.
水平有限, 如有錯(cuò)誤, 歡迎拍磚.