天天看點

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中設定:

  該配置檔案中配置了一個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不斷的建立。