最近在專案中遇到 由非同步執行任務導致的request中的請求入參物件被不同請求汙染的多執行緒問題;
在同事的研究下,發現了一把request 在原始碼層面是如何進行**處理的;因此將其中涉及到的主要原始碼進行展示:
首先,根據原始碼斷點我們發現request採用了包裝器模式,而最核心處理的request是
org.apache.catalina.connector.request;我們獲取請求引數的方法原始碼為:
public mapgetparametermap()
//當未鎖住的時候進行初始化和賦值,並在賦值結束後將其鎖住
//在parametermap 被釋放鎖之後第一次呼叫執行(可能被非同步呼叫執行,可能被下乙個請求物件執行)
enumerationenumeration = getparameternames();
while (enumeration.hasmoreelements())
parametermap.setlocked(true);
return parametermap;
}
從我們獲取請求request 中的請求入參可知:
當一次請求結束前,我們將request交給乙個非同步執行的執行緒使用,會出現兩種情況
1、在下一次請求前執行getparametermap() 方法
2、在下一次請求後執行getparametermap() 方法
而這兩種情況都會到來問題:
首先,在下一次請求前執行getparametermap() 方法 這個時候我們的請求enumerationenumeration 物件已經被清理,沒有任何入參,並且parametermap物件被鎖住,導致下乙個請求無法進行引數設定,就會出現前端請求引數無法設定進去的現象;
第二種情況,在下一次請求後執行getparametermap() 方法,這個時候下乙個請求的入參會正常執行,但是因為下一次請求的入參被設定進來,並且我們是引用指向,parametermap物件並不會被真正的被重新建立,他只是通過lock控制了資料的安全,因此我們一步請求的執行緒依然指向下乙個介面請求的parametermap,並且其中的引數值為下乙個請求介面的入參值。
為了更便於了解真相,下面我們把request的重置方法原始碼貼出來:
public void recycle() catch (ioexception ignored)
}parts = null;
}partsparseexception = null;
locales.clear();
localesparsed = false;
secure = false;
remoteaddr = null;
remotehost = null;
remoteport = -1;
localport = -1;
localaddr = null;
localname = null;
attributes.clear();
sslattributesparsed = false;
notes.clear();
recyclesessioninfo();
recyclecookieinfo(false);
//入參內容儲存map,
if (globals.is_security_enabled || connector.recycle_facades) else
if (globals.is_security_enabled || connector.recycle_facades)
if (inputstream != null)
if (reader != null)
}asyncsupported = null;
if (asynccontext!=null)
asynccontext = null;
}
其中對parametermap 的操作**如下:
//入參內容儲存map,
if (globals.is_security_enabled || connector.recycle_facades) else
Request原始碼總結
看了request原始碼一周,流程懂了,但是很多細節還沒仔細查。總結一下 request.get 1.設定預設引數,allow redirects true,2.進入request方法,用session.session類持久化request 3.進入session類,設定預設請求頭,設定預設請求鉤子...
nginx原始碼分析 從原始碼看nginx框架總結
nginx原始碼總結 1 中沒有特別繞特別彆扭的編碼實現,從變數的定義呼叫函式的實現封裝,都非常恰當,比如從函式命名或者變數命名就可以看出來定義的大體意義,函式的基本功能,再好的架構實現在編碼習慣差的人實現也會黯然失色,如果透徹理解 的實現,領悟架構的設計初衷,覺得每塊 就想經過耐心雕琢一樣,不僅僅...
從原始碼分析StringUtils包
今天用到stringutils.join方法,閒來無聊,看了下原始碼 當然不可能自己分析,你傻啊,在這裡推薦乙個別人分析的 首先導包 import org.apache.commons.lang3.stringutils 我在這裡呼叫的是stringutils.join方法 public stati...