本身动手写压力测试-三剑客HttpClient+Async+Parallel

曾经沧海难为水 php

信息如水 压力如潮

功能实现阶段,咱们对得要处理的信息分析得很细致,很透彻,所谓细如丝,透如水。然而,到了产品的阶段,要处理的信息却如同潮洪而至,本来的假设预想,统统被击成了碎片。这时候产生的错误和问题,很难在开发机上重现。 html

若是说用户验收测试是对功能实现的检查,须要滴水不漏;压力测试则是容量的考验,迎接浪的洗礼。 node

(本文版权属于© 2012 - 2013 予沁安apache

环肥燕瘦

压力测试的工具颇多,尤为是HP的LoadRunner甚至成为了行业标准。但是,在研究和考察的过程当中,内心却慢慢有了质疑,我是否非得用这些工具吗? 一则,它们是商业软件,价格不菲;二则,仍是由于是商业软件,功能太多,太庞大,不少东西我都不须要。为何不本身作一个简单实用的呢? 编程

小赵研究Selenium时,我以为用他用的语法很贴近业务语言,因而我提出一个问题,能够用于压力测试吗?他说不行,由于Selenium是要彻底启动浏览器。平时,看起来瘦小的浏览器,其实很耗资源,特别是与压力测试的容量来比,浏览器是个彻彻底底的大胖子。你能够试一下,在你的机器上同时开启100个浏览窗口,会是个什么情况。 浏览器

苗条美人 HttpClient

否认了Selenium以后,很快就找到了个人目标HttpClient (其实还有个前生WebClient,后面有叙)。从名称,咱们就能够知道,它已经定位到很低Http层,这一层是效率与易用的一个最佳平衡点。可是,它是.Net 4.5下的部件,在.Net 4.0必须用NuGet来下载。 网络

查看了不少资料之后,我能够确信,HttpClient正是我想要的。她还有一个很大的特点,彻底只提供异步接口。这其实是另外一种大瘦身,耗用资源上的瘦身,HttpClient正式我要的窈窕淑女。 app

前生:WebClient 框架

var values = new NameValueCollection();
foreach (var key_value in ui.FormData)
{
	values.Add(key_value.Key, key_value.Value);
}
var client = new WebClient();
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
Console.WriteLine(string.Concat(base_site + ui.Path, ui.Method.ToString().ToLower(), values));
byte[] result = client.UploadValues(base_site + ui.Path, ui.Method.ToString().ToLower(), values);
string ResultAuthTicket = Encoding.UTF8.GetString(result);
Console.WriteLine(client.BaseAddress);
Console.WriteLine(client.ResponseHeaders.ToString());
Console.WriteLine(ResultAuthTicket);

HttpClient的Async方法,注意最后的Wait()有把异步转化为了同步 异步

var form_data=new Dictionary<string, string>();
form_data.Add("system_account","test1@skight.com");
form_data.Add("system_password","123456");
var values = new NameValueCollection();
foreach (var key_value in form_data)
{
	values.Add(key_value.Key, key_value.Value);
}
var client = new HttpClient();

client.GetStringAsync("http://esr20syst.skight.com/District/03/UserLogin.do")
	  .ContinueWith(
		  t =>
		  {
			  Console.WriteLine("Time {0}", DateTime.Now);
			  Console.WriteLine(t.Result);
		  })
	  .Wait();

Sync 仍是Async 这,是一个问题

.Net 4,5 出来以后,一直没有对它的新功能和特性太在乎。只是公司升级使用VS2012,除了灰不溜秋的界面,而所谓的性能提升(其实,是VS2010太次)以外,也没有特别感受。

然而,此次在查看HttpClient资料时,却意外发现了.Net 4.5 语法级别的一个亮点: Asyn和Await。这让异步编程更简便,更漂亮。看来,从此异步编程是一个大潮流,微软也不惜余力。

新语法应用以后的效果,彷佛和平时的同步编码没有太大区别,除了不时冒出来的Await和Async

var form_data=new Dictionary<string, string>();
form_data.Add("system_account","test1@skight.com");
form_data.Add("system_password","123456");
foreach (var key_value in form_data)
{
	values.Add(key_value.Key, key_value.Value);
}
var httpClient = new HttpClient();
var content= await httpClient.GetStringAsync("http://esr20syst.skight.com/District/03/UserLogin.do");
Console.WriteLine(content.Result);

异步性能的福利是不可随小觑的。以前,有Node.js构建的的Web服务比Apache快不少(http://zgadzaj.com/benchmarking-nodejs-basic-performance-tests-against-apache-php)就是得益于Javascript天生的函数回调方式支持的异步运行。如今有.Net对Async的友好支持,以及大量组件基于异步方式的重写。听说,微软推荐,凡是运行时间超过20毫秒的功能,就要用异步方式来写。HttpClient就是一个例子,它的前身WebClient就不具异步调用,而HttpClient干脆就不提供同步接口。

平行宇宙 Parallel

其实,不管是的Async仍是Parallel,都是语法糖,但是做为辛苦的开发者,咱们好的就是这一口。

Async让咱们发出网络请没必要再等待,Parallel让咱们很容易的持续发出平行请求,这就是一个彻底的压力测试模型了。我这里简单设置了一个100 * 10 个请求。没有具体计算,共发出多少个请求,我只知道,多得已经足够让个人系统重现产品机上的问题了。

Parallel.For(1, 1000, i =>
	Parallel.For(1, 5, case_number =>
	   LoginScenario(case_number)
		   .run_by(runner)
	));

:个人业务语法糖DSL

这里是我对系统页面操做的定义代码,用语法糖DSL的方式实现,必定程度上实现了需求即代码即文档的要求吧。这部分代码不能直接运行,由于它使用了我本身的Web框架,从而能够用强类型自动生成URL。这里提供出来只是做参考,做为示例的一部分。

private static Scenario LoginScenario(int case_number)
{
	return
		UI.context(Keys.Context.District.with_value(DistrictIdentifier.of("03")))
		  .to<UserLoginGet>()
		  .then(
			  UI.input(SystemPayloadKeys.Account.with_value(string.Format("test{0}@skight.com", case_number)))
				.and_input(SystemPayloadKeys.Password.with_value("123456"))
				.to<UserLoginPost>());
}

(本文版权属于© 2012 - 2013 予沁安 | 转载请注明做者和出处

相关文章
相关标签/搜索