30行代码搞定WCF并发性能测试

时间:2021-08-05 00:32:38

【以下只是个人观点,欢迎交流】

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对单位时间的并发请求的最大支持数目。