Session對性能測試的影響
Session介紹
Cookie是Web產品測試過程中不可缺少的一部分,我們需要通過Cookie信息辨別用戶,得到屬于自己的結果數據,例如DWR接口測試過程中,需要在請求頭信息中傳入測試用戶的cookie信息,才可以得到該用戶學習的課程,發(fā)表的博客,或者關注的用戶等。Cookie信息通過模擬登陸操作就可以獲得。但是,你有沒有注意到你獲得的Cookie是由什么組成的?是否包含NTES_SESS信息,是否包含SessionID信息?
NTES_SESS是URS返回的Cookie信息,NTESSTUDYSI是云課堂返回的Session信息,NTESSTUDYSI存儲SessionID信息,不同的產品會配置不同的變量名。這個信息對于接口測試來說并不是必須的,但是卻會在性能測試過程中起到很關鍵的作用。Cookie和Session有什么區(qū)別,為什么性能測試過程中必須需要Session信息?下面,我們一一闡述:
Cookie是什么:
cookie是小甜餅、小型文本文件,因為HTTP協議是無狀態(tài)的,瀏覽器無法區(qū)分這次請求來自于哪個瀏覽器,因此產生了隨著HTTP請求一起被傳遞給服務器的Cookie信息。Cookie是保存在客戶端的,存在內存中的cookie,瀏覽器關閉后就消失了,存在時間是短暫的;存在硬盤中的Cookie,但存儲時間長度超過過期時間或者用戶手動清除時,cookie信息會消失。
Session是什么:
Session是會話,當用戶第一次對網站服務器發(fā)生請求時,服務器會創(chuàng)建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發(fā)送并存放到客戶端的硬盤文件上,并設置Cookie的過期時間,以便于實現用戶的自動登錄和網站內容自定義。
我們在執(zhí)行接口測試之前,首先會通過URS得到用戶Cookie信息,這份Cookie信息中至少會得到NTES_SESS字段對應的Values值,如果在獲取Cookie時,我們同時跳轉到產品頁面,向該產品服務器發(fā)送請求(例如云課堂),那么在我們得到的Cookie信息中同樣存在NTESSTUDYSI字段,該字段就是該產品的Tomcat服務器產生的32位的SessionID +jvmRoute設置的后綴名。在做接口測試時,如果請求頭中沒有傳入SessionID信息,那么每次執(zhí)行時,Tomcat都會重新生成一份Session;即便你傳入該SessionID信息,如果SessionID過了超時時間設置,Tomcat還是會重新生成一份,Tomcat默認的Session過期時間為30Min。
性能影響
雖然只是一個小小的SessionID,卻會對性能測試的產生很大的影響:
1、Session缺失:
在做Lofter產品的性能測試時,測試getHomePage接口,發(fā)現響應時間比較慢,JVM內存在測試過程中一直增長,Young GC收集不過來,Old區(qū)內存不斷增長,最終會導致頻繁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都會檢查是否存在該標識信息,如果沒有則會創(chuàng)建。如果我們測試過程中有幾十萬次請求,那么Tomcat會創(chuàng)建幾十萬個Session信息,假設一條Session需要2K的數據,那幾十萬的Session可能會使得Session容器占用上百兆的空間。同時需要注意,因為我們每個請求都會創(chuàng)建Session,這個Session是創(chuàng)建了以后不會被使用的(下次請求中依然沒有攜帶SessionID),即垃圾Session,但是垃圾Session在過期之前是會一直存在內存中的,默認的Session保存時間是30Min,這樣的垃圾Session會在內存中保存至少30Min,如果在這30Min中內我們不停的發(fā)送請求,Session容器占用的內容空間會 不斷擴大,最終會影響我們的測試結果。
2、Session過期
即便我們在請求中加入了SessionID,但是還可能會產生不停的創(chuàng)建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,可是為什么還是會不停的創(chuàng)建Session?
一般我們的產品架構是Nginx+Tomcat方式,靜態(tài)請求走Nginx,動態(tài)請求通過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中的后綴來查找請求發(fā)送到哪個Tomcat,例如NTESSTUDYSI=1816E5ECBC052F6ABA420FEE7B06DA86.qa18-8010;就會把帶這個SessionID的請求發(fā)送到 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,當發(fā)送請求到Nginx時,檢測到SessionID的后綴和設置的server服務器無法匹配,則會丟失session,使得發(fā)送到Tomcat的動態(tài)請求依舊是沒有Session信息的請求,造成session丟失,測試過程中還會有session不斷的創(chuàng)建。
posted on 2013-04-01 10:10 順其自然EVO 閱讀(513) 評論(0) 編輯 收藏 所屬分類: 性能測試