注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

网易杭州 QA Team

务实 专注 分享 做有态度的QA

 
 
 
 
 

日志

 
 

多种模拟并发http请求方式的实现方法  

来自cen   2012-07-05 19:34:25|  分类: 接口测试 |举报 |字号 订阅

  下载LOFTER 我的照片书  |

性能测试中,经常需要对服务器模拟并发http请求。现有多种方式实现,可以在性能测试组织测试脚本阶段根据实际需求、场景或测试环境的不同酌情选择不同的实现方式。

 

(一)  Jython脚本调用grinder框架

 

通过jython脚本调用grinder框架实现,利用grinder框架实现并发和http请求组织和收发。Grinder框架底层用socket来实现发送请求。

以一个POST请求DWR接口为例,该实现方式基本代码如下:

# The Grinder 3.2

headers0= \

  [ NVPair('Accept', '*/*'),

    NVPair('Accept-Language', 'zh-cn'),

NVPair('Referer', 'http://www.lofter.com/'), ]

url0 = 'http://www.lofter.com:80'

request0 = HTTPRequest(url=url0, headers=headers0)

request0 = Test(0, 'POST PostBean.getPostHots.dwr').wrap(request0)

HTTPPluginControl.getConnectionDefaults().useCookies = 0

 

class TestRunner:

  """A TestRunner instance is created for each worker thread."""

def page171(self):

    """POST PostBean.getPostHots.dwr (request 0)."""

        result =request0.POST('/dwr/call/plaincall/PostBean.getPostHots.dwr',      '''callCount=1\nscriptSessionId=${scriptSessionId}187\nc0-scriptName=PostBean\nc0-methodName=getPostHots\nc0-id=0\nc0-param0=number:1067622\nc0-param1=number:343058\nc0-param2=number:10\nc0-param3=number:0\nbatchId=826545''',

      ( NVPair('Content-Type', 'text/plain'),

NVPair('Cookie',cookie),)

       return result;

def __call__(self):

     """This method is called for every run performed by the worker thread."""     

 self.page171()

 

这里http请求的组织和收发用到grinder框架下HTTPRequestNVPair等类。

这里的TestRunner类起到并发的作用,跑测试的时候,grinder每个worker线程会自动创建一个TestRunner实例。比如性能测试时要模拟50个并发用户访问,grinder则会实例化50TestRunner类,每个实例一个线程,类中的__call__(self)方法每run一次则会调用执行一次,模拟用户的频繁点击(反复run)。这样就可以模拟多用户并发持续访问某站点的场景。

    这个方式完全用grinder框架实现,grinder框架有着良好的性能测试数据收集统计功能,使用方便。

 

(二)  Grinder并发调用httpclient3

这里jython脚本中保留(一)中的TestRunner__call__,grinder框架中的类只起到并发用户,反复run和性能测试数据收集统计功能。

http请求组织和发送用httpclient3实现(commons-httpclient-3.1.jar,基本实现代码如下:

 

HttpClient httpclient = new HttpClient();//实例化一个httpclient

String posturl = "***********";

PostMethod post = new PostMethod(posturl);//POST请求

//组织请求头部

post.setRequestHeader("Accept", "*/*");

...

//组织请求Body

NameValuePair callCountPair = new NameValuePair("callCount", "1");

...

NameValuePair[] namevaluepair = new NameValuePair[] { callCountPair,...};

post.setRequestBody(namevaluepair);

//发送

httpclient.executeMethod(post);

 

 ()Grinder并发调用httpclient4

思路和(二)类似,只是把http请求的组织换成httpclient4实现。Httpclient4相对httpclient3变化很大, httpclient4(httpclient-4.0.3.jar,httpcore-4.0.1.jar),基本实现代码如下:

 

DefaultHttpClient client = new DefaultHttpClient();

 

String url = "******";

 

HttpPost post = new HttpPost(url);

//组织头部

Header[] allHeader = new BasicHeader[8];

allHeader[0] = new BasicHeader("Accept","*/*");

//组织Body

List<NameValuePair> pairs = new ArrayList<NameValuePair>();

pairs.add(new BasicNameValuePair("callCount","1"));

post.setHeaders(allHeader);

 

UrlEncodedFormEntity formEntiry = new UrlEncodedFormEntity(pairs); 

post.setEntity(formEntiry);

//发送

client.execute(post);

 

()java多线程并发

这个方式完全使用java实现。http请求的组织和发送可以使用(二)或(三)的httpclient实现。

   并发则使用java.util.concurrent包下的并发框架executor,和thread实现比较,它的线程和任务之间解耦性更好。

  public class HTTPRequest001  implements Runnable {

      public void run() {

       //这里实现发送请求

}

 

  public static void main(String[] args) {

  ExecutorService service = Executors.newFixedThreadPool(50);

  for (int i = 0; i < 50; i++)

     service.execute(new HTTPRequest001());//并发50个用户

    

}

}

 

这种方式需要自己实现grinder框架的相关功能和统计相关性能指标。主要包括并发用户数设置(通过并发框架设置并发用户数),测试时间设置(主线程sleep测试时间后结束各子线程),TPS(统计成功的请求数/测试时间)和ART统计(发送请求的代码语句前后取系统时间)。

(五)线程安全

     Httpclient34组织发送请求实现中,如果每个线程使用单独的httpclient实例组织则不影响,如果在各线程外使用公共的实例,则需考虑线程安全。

Httpclient3使用MultiThreadedHttpConnectionManager类,Httpclient4使用ThreadSafeClientConnManager类来支持线程安全。

() 总结

1、直接使用grinder框架开发测试脚本效率高,使用方面,有着良好的性能测试数据收集统计功能。

2、有些请求场景直接用grinder框架较难实现,比如组内一位同学要在请求未完成情况下直接断开连接,grinder框架貌似不提供相应显式方法。直接用httpclient组织脚本比较灵活。

3httpclient3httpclient4 性能上相差不大,深入的区别可以进一步调研。

  

多种模拟并发http请求方式的实现方法 - 网易杭州QA - 网易杭州 QA Team

  

4grinder框架实现相对直接java实现cpumem资源消耗要大一些

    

多种模拟并发http请求方式的实现方法 - 网易杭州QA - 网易杭州 QA Team

 

实际性能测试中可以根据实际需求、场景或测试环境的不同灵活选择不同的实现方式。

  评论这张
 
阅读(5897)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016