Session對性能測試的影響(轉 )

Session介紹

  Cookie是Web產品測試過程中不可缺少的一部分,我們需要通過Cookie信息辨別用戶,得到屬於自己的結果數據,例如DWR接口測試過程中,需要在請求頭信息中傳入測試用戶的cookie信息,纔可以得到該用戶學習的課程,發表的博客,或者關注的用戶等。Cookie信息通過模擬登陸操作就可以獲得。但是,你有沒有注意到你獲得的Cookie是由什麼組成的?是否包含NTES_SESS信息,是否包含SessionID信息?

  NTES_SESS是URS返回的Cookie信息,NTESSTUDYSI是雲課堂返回的Session信息,NTESSTUDYSI存儲SessionID信息,不同的產品會配置不同的變量名。這個信息對於接口測試來說並不是必須的,但是卻會在性能測試過程中起到很關鍵的作用。Cookie和Session有什麼區別,爲什麼性能測試過程中必須需要Session信息?下面,我們一一闡述:

  Cookie是什麼:

  cookie是小甜餅、小型文本文件,因爲HTTP協議是無狀態的,瀏覽器無法區分這次請求來自於哪個瀏覽器,因此產生了隨着HTTP請求一起被傳遞給服務器的Cookie信息。Cookie是保存在客戶端的,存在內存中的cookie,瀏覽器關閉後就消失了,存在時間是短暫的;存在硬盤中的Cookie,但存儲時間長度超過過期時間或者用戶手動清除時,cookie信息會消失。

  Session是什麼:

  Session是會話,當用戶第一次對網站服務器發生請求時,服務器會創建Session信息,生成SessionID用來唯一標識用戶,並會把該SessionID返回給客戶端瀏覽器(只存在內存,並不存在硬盤中),在會話結束之前的每次請求,瀏覽器會自動將該SessionID附加在請求頭信息中,服務端接受請求時,檢測是否存在SessionID(不存在或者Session過期都會重新生成Session),並通過該SessionID以鍵值對的方式查詢用戶信息。服務端的Session使用類似散列表的結構存儲用戶信息。

  Session的常見實現形式是會話Cookie(Session Cookie),即未設置過期時間的Cookie,這個Cookie的默認生命週期爲瀏覽器會話期間,只要關閉瀏覽器窗口,Cookie就消失了,這種形式的Session是和Cookie綁定在一起的。而平常所說的Cookie主要指的是另一類Cookie——持久Cookie(Persistent Cookies)。持久Cookie是指存放於客戶端硬盤中的Cookie信息(設置了一定的有效期限)。持久Cookie一般會保存用戶的用戶ID,該信息在用戶註冊或第一次登錄的時候由服務器生成包含域名及相關信息的Cookie發送並存放到客戶端的硬盤文件上,並設置Cookie的過期時間,以便於實現用戶的自動登錄和網站內容自定義。

  我們在執行接口測試之前,首先會通過URS得到用戶Cookie信息,這份Cookie信息中至少會得到NTES_SESS字段對應的Values值,如果在獲取Cookie時,我們同時跳轉到產品頁面,向該產品服務器發送請求(例如雲課堂),那麼在我們得到的Cookie信息中同樣存在NTESSTUDYSI字段,該字段就是該產品的Tomcat服務器產生的32位的SessionID +jvmRoute設置的後綴名。在做接口測試時,如果請求頭中沒有傳入SessionID信息,那麼每次執行時,Tomcat都會重新生成一份Session;即便你傳入該SessionID信息,如果SessionID過了超時時間設置,Tomcat還是會重新生成一份,Tomcat默認的Session過期時間爲30Min。

  性能影響

  雖然只是一個小小的SessionID,卻會對性能測試的產生很大的影響:

  1、Session缺失:

  在做Lofter產品的性能測試時,測試getHomePage接口,發現響應時間比較慢,JVM內存在測試過程中一直增長,Young GC收集不過來,Old區內存不斷增長,最終會導致頻繁Full GC,使用Jmap定位到堆內存中java.util.concurrent.ConcurrentHashMap$Segment對象不斷增加,但是並不知道這個對象時誰在什麼時候產生的。我們Dump出來此時的堆內存,使用MAT (Memory Analyzer Tool)工具進一步分析,到底是什麼操作產生了大量的ConcurrentHashMap$Segment。

  由上圖可以看到這個對象是由org.apache.catalina.session.StandardManager產生的,session.StandardManager就是存儲Session的容器。



通過了解Session的原理得知,我們在測試過程中,只是傳入了Cookie信息,在Cookie中沒有包含SessionID信息,所以每次請求時,Tomcat都會檢查是否存在該標識信息,如果沒有則會創建。如果我們測試過程中有幾十萬次請求,那麼Tomcat會創建幾十萬個Session信息,假設一條Session需要2K的數據,那幾十萬的Session可能會使得Session容器佔用上百兆的空間。同時需要注意,因爲我們每個請求都會創建Session,這個Session是創建了以後不會被使用的(下次請求中依然沒有攜帶SessionID),即垃圾Session,但是垃圾Session在過期之前是會一直存在內存中的,默認的Session保存時間是30Min,這樣的垃圾Session會在內存中保存至少30Min,如果在這30Min中內我們不停的發送請求,Session容器佔用的內容空間會 不斷擴大,最終會影響我們的測試結果。

  2、Session過期

  即便我們在請求中加入了SessionID,但是還可能會產生不停的創建Session問題,這是爲什麼?因爲Session是存在過期時間的,默認的Tomcat中web.xml中設置的session過期時間爲30Min,如果我們得到的SessionID在30Min後使用,依據Tomcat的Session機制,首先會檢查是否存在SessionID,如果有的話,檢測是否過期,如果傳入的SessionID已經過期,Tomcat還是會每次都自動生成Session信息。

  Mark,Session的過期時間有三種設置方式:一種是Tomcat的配置文件web.xml中設置,一種是webroot項目代碼中的配置文件web.xml中設置,一種是代碼中設置session.setMaxInactiveInterval(15*60),所以我們在測試中要記得檢測和確認這三個地方。

  3、SessionID後綴不匹配

  在測試雲課堂項目中,我明明已經修改了每個地方的Session過期時間,請求中傳入了沒有過期的SessionID,可是爲什麼還是會不停的創建Session?

  一般我們的產品架構是Nginx+Tomcat方式,靜態請求走Nginx,動態請求通過Nginx訪問到Tomcat。Nginx處理Session採用了session sticky方案,需用到第三方模塊jvm_route,需要在Nginx的配置文件中upstream.conf中設置:

 

 

upstream study {
server 10.120.36.68:8010 srun_id=qa18-8010;
server 10.120.36.97:8010 srun_id=qa19-8010;
jvm_route $cookie_NTESSTUDYSI reverse;
keepalive 100;
}

 

 

  該配置文件中配置了一個Nginx連接兩個Tomcat,當請求過來時,會依據SessionID中的後綴來查找請求發送到哪個Tomcat,例如NTESSTUDYSI=1816E5ECBC052F6ABA420FEE7B06DA86.qa18-8010;就會把帶這個SessionID的請求發送到 10.120.36.68(qa18)這臺機器上去。

  在qa18這臺機器的Tomcat配置文件server.xml中,會設置jvmRoute="qa18-8010",這樣保證生成的SessionID的後綴是qa18-8010,如果這個兩個後綴不一致的話,同樣會出現問題。

  例如如果Nginx配置文件中upstream.conf中設置的srun_id=qa18-8010,而tomcat配置文件中設置的jvmRoute="qatest18-8010",那麼獲取Cookie得到的SessionID後綴則爲qatest18-8010,當發送請求到Nginx時,檢測到SessionID的後綴和設置的server服務器無法匹配,則會丟失session,使得發送到Tomcat的動態請求依舊是沒有Session信息的請求,造成session丟失,測試過程中還會有session不斷的創建。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章