【以下只是个人观点,欢迎交流】
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对单位时间的并发请求的最大支持数目。