【以下只是个人观点,欢迎交流】
30行代码搞定WCF并发性能 轻量级测试。
1. 调用并发测试接口
static void Main()
{
List<object> data_list = new List<object>();
LoginContextBase item = LoginContextBase.CreateLoginContext(AccountEnumType.Ad); //new AdLoginContext();
item.LoginAccount = "kevin.tian";
data_list.Add(item);
int num = 500;
RunMutiThread(
// 执行并发测试代码
(object_p1) =>
{
LoginContextBase ctx = object_p1 as LoginContextBase;
IAuthentication proxy_authen_i = PublicProxy.GetAuthenticationService();
ICryptHelper proxy_crypt_i = PublicProxy.GetCryptHelperService();
ctx.FuncID = proxy_authen_i.GetFunctionID(PublicConfig.DBKey_Basic_Secure, PublicConfig.FuncTitle);
ctx.LoginPwd = proxy_crypt_i.EncryptDES_ByCustom("1234#abc");
ActionResult<IUser> ret = proxy_authen_i.Login(PublicConfig.DBKey_Basic_Secure, ctx);
ProxyClose<IAuthentication>.Dispose(proxy_authen_i);
ProxyClose<ICryptHelper>.Dispose(proxy_crypt_i);
return ret;
},
// 记录每次测试日志
(begin_i, index_i, object_funcWork_Result) =>
{
ActionResult<IUser> ret = object_funcWork_Result as ActionResult<IUser>;
if (!ret.IsSuccess || ret.IsError)
{
PublicLogger.Logger_PublicProxy.Info(string.Format("{0}/{1} user to login, result = {2}"
, index_i.ToString("00000")
, num.ToString("00000")
, ret.IsSuccess)
, begin_i);
}
},
// 最大并发数目
num,
// 测试参数列表
data_list); }
2.并发测试接口实现
static void RunMutiThread(
Func<object, object> func_work, // 并发测试函数<传入参数,返回结果>
Action<DateTime, int, object> func_log, // 日志函数<本次开始时间,本次顺序编号,本次测试执行结果>
int num, // 理论最大并发数量
List<object> data_list) // 参数列表
{
object flag_lock = 1;
int flag_num = 0;
AutoResetEvent wait = new AutoResetEvent(false);
DateTime begin = DateTime.Now;
PublicLogger.Logger_PublicProxy.Info(string.Format("begin test: user's count ={0}", num.ToString("00000")));
for (int i = 0; i <= num; i++)
{
int index_i = i;
ThreadPool.QueueUserWorkItem((o) =>
{
// 获取本次参数
DateTime begin_i = DateTime.Now;
object data = data_list.Count > 1 ? data_list[index_i] : data_list[0];
try
{
#region more code
// 执行并发业务
object result = func_work.Invoke(data);
// 记录并发日志
func_log.Invoke(begin_i, index_i, result);
lock (flag_lock)
{
flag_num++;
if (flag_num == num)
{
// 所有并发子进程执行完毕
wait.Set();
}
}
#endregion
}
catch (Exception ex)
{
PublicLogger.Logger_PublicProxy.Info(string.Format("{0}/{1} user to login, result = {2}"
, index_i.ToString("00000")
, num.ToString("00000")
, "Exception: " + ex.Message)
, begin_i);
}
}, index_i);
}
// 等待并发线程结束
wait.WaitOne();
PublicLogger.Logger_PublicProxy.Info(string.Format("end test: user's count ={0}\r\n", num.ToString("00000")), begin);
}
3. 查看日志,并且算出 平均值
[2013-12-03 11:01:01:423][Info] : msg=begin test: user's count =00100
[2013-12-03 11:01:13:097][Info] : msg=taketime: 00:00:11.6741673 | end test: user's count =00100
[2013-12-03 11:04:23:211][Info] : msg=begin test: user's count =00100
[2013-12-03 11:04:28:388][Info] : msg=taketime: 00:00:05.1775177 | end test: user's count =00100
[2013-12-03 11:16:13:814][Info] : msg=begin test: user's count =01000
[2013-12-03 11:16:47:939][Info] : msg=taketime: 00:00:34.1270000 | end test: user's count =01000 结论:由于客户端电脑配置一般,大致一秒钟可以发起10个线程提交给服务器处理。可以在几台客户机器机器上运行该代码, 模拟更多的并发进程,然后用总的成功请求数量/执行时间,即可得到平均的单位1秒内的并发支持数目。 备注:由于使用Func和Action做通用接口方便测试不同的WCF接口,导致程序发起线程的性能受到影响。 目测是从1秒内50个线程降低为10个线程。用户可以根据自己需要,不使用函数代理或者同时在多个客户端 执行该测试工具,以便检验服务端WCF对单位时间的并发请求的最大支持数目。