|
HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的。session机制则是又一种在客户端与服务器之间保持状态的解决方案。session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
一.Session机制
当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 ,称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID。比如weblogic对于web应用程序生成的cookie:JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID。IIS对于web应用程序生成的cookie:ASP.NET_SessionId=r4fbxvayqhjj3z45thwyfqv1,它的名字是ASP.NET_SessionId。
由于cookie可以被人为的禁止,必须有其它机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为:http://...../xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK ... 99zWpBng!-145788764
这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。
另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如下面的表单<form name=\"testform\" action=\"/xxx\">
<input type=\"text\">
</form>
在被传递给客户端之前将被改写成
<form name=\"testform\" action=\"/xxx\">
<input type=\"hidden\" name=\"jsessionid\"
value=\"ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764\">
<input type=\"text\">
</form>
不过目前这种技术现在已较少应用。实际上这种技术可以简单的用对action应用URL重写来代替。
二.Performer性能测试中session解决方案
使用Performer进行web应用性能测试时,如果应用服务器是通过url或者表单隐藏字段来保存sessionid,那在录制好脚本之后,可以使用TrueLog Explorer中的Customize Session Handling将录制捕获的服务器端返回html文档跟回放的产生的html文档进行对比,从中要到每次动态生成的不一样的sessionid,将其加以参数化后就能解决问题。对于使用cookie存放sessionid的方式,由于TrueLog Explorer对比的是录制跟回放时的html文档,可能无法查找到录制跟回放时的sessionid差异,例如IIS在服务器跟客户端的交互中将sessionid放在http头中。此时,performer为了保持服务器跟客户端的会话状态,采用了为每个虚拟用户维护一个cookie database,且cookie database不支持跨transaction,即如果登录跟业务操作分开录制再两个transaction中时,登录transaction中的cookie database会在该transaction执行完后被清空,业务操作所在的transaction无法沿用登录transaction的cookie database,此时必须恢复cookie database至登录transaction结束时的状态,performer提供了一系列操作cookie database的函数,如下是一个实现方案。
function StoreCookies(lcookies:array of string;lncookie:number)
var
lflag :string;
lhcookie :boolean;
begin
lncookie := 0;
lhcookie := WebCookieListFirst(lflag, STRING_COMPLETE);
while lhCookie do
lncookie := lncookie + 1;
lhCookie := WebCookieListNext(lflag, STRING_COMPLETE);
lcookies[lncookie] := lflag;
end;
end StoreCookies;
function RepairCookies(lcookies:array of string;lncookie:number)
var
lcount :number;
ldomain :string;
lpath :string;
lurl :string;
begin
if lncookie <> 0 then
for lcount := 1 to lncookie do
StrSearchDelimited(ldomain,STRING_COMPLETE, [Page]
lcookies[lcount], \"domain=\",
1,\";\",1,STR_SEARCH_FIRST);
StrSearchDelimited(lurl,STRING_COMPLETE,
lcookies[lcount],\"path=\",
1,\";\",1,STR_SEARCH_FIRST);
lurl := \"http://\" + ldomain + lpath;
WebCookieSet(lcookies[lcount],lurl);
end;
end;
end RepairCookies;
StoreCookies函数用在登录transaction结束处,将当前cookie database中所有的cookie保存进全局字符串数组中,供后面的RepaireCookies函数使用。RepaireCookies函数用在业务transaction的开始处,恢复cookie database,session问题得到解决 |
|