WCF+JSON+实体对象与WebService+DataSet效率大比拼
在整合数据的方式上存在分歧有两种方案方案1将所有系统的客户数据整合到一个数据库中--“中心数据库”所要的工作主要有设计一个“超级客户数据表”尽可能多的包含各个业务系统的客户数据表的字段然后再开发一套程序完成各个业务数据库与“中心”数据库直接的数据导入更新同步等方案2不设立“中心数据库”数据从各个业务系统中按需查询在内存中整合查询出的部分数据为一个内存数据集数据集的表头根据配置决定所需要的工作相对复杂需要在各个业务系统中开发和部署“客户数据服务”还要开发一个代理服务来整合数据好处是方案1的数据更新同步问题不存在了数据维护量大大减轻。我们采用WCF服务来实现2号方案具体来说就是在各个业务系统中开发各自的WCF客户数据服务以下简称外围服务再开发一个整合数据的WCF代理服务在外围服务和代理之间使用TCP通道进行数据的高速传输而在客户端和代理服务端为了让IE这样的客户端能够使用JSON格式的数据所以我们在代理服务端采用WCFJSON实体类 的方式提供服务。经过长达半个月的可行性测试开发POC程序方案2终于成功实现了但公司其它同事对这样的“分布式计算”模式很是怀疑因为以前从没有人这么做过况且公司是以做数据起家的对“集中式数据管理”的优势深信不疑要求我们搭建一个测试环境进行对比测试。测试环境2号方案测试环境有5台服务器ABCDE在每台服务器上面部署一个WCF客户数据服务程序每台服务器上面都有一个SQLSERVER2008 格式的客户数据库服务程序访问自己机器上面的数据库每个数据库的客户数据是500万条5台服务器合计有2500万条客户数据任意两台服务器之间的客户数据都是不重复的代理服务程序和客户端程序都在我们的开发机器上面。每个外围服务程序从自己的数据库中取2万条记录合计10万条从第1万页数据每页2万条开始取 1号方案测试环境提供一台服务器Z它上面仅仅有一个SQLSERVER2008 格式的客户数据库但它有2500万条客户数据数据都是不重复的访问数据库的Web服务和客户端程序也在我们的开发机器上面。Web服务将每次从该数据库中取10万条记录从第1万页数据每页2万条开始取 测试结果2号方案测试情况我们监控代理服务调用各个外围服务的数据下面是VS2008的测试窗口输出的结果有些服务器没有正常运行故工作的服务器没有5台2010/7/7 16:02:55 服务器192.168.50.25:8119 已经成功完成任务距离开始时间ms2633.1506线程 0x1550 已退出返回值为 0 (0x0)。2010/7/7 16:02:56 服务器192.168.50.19:8119 已经成功完成任务距离开始时间ms3180.1819线程 0x160c 已退出返回值为 0 (0x0)。2010/7/7 16:02:56 服务器192.168.50.15:8119 已经成功完成任务距离开始时间ms3457.1978线程 0x8c0 已退出返回值为 0 (0x0)。2010/7/7 16:02:59 服务器192.168.50.5:8119 已经成功完成任务距离开始时间ms6033.3451线程 0x14a4 已退出返回值为 0 (0x0)。总共耗时(ms)6041.3456线程 0x1020 已退出返回值为 0 (0x0)。排除执行时间比较长的服务器评价时间不到4秒此例实际总耗时6秒左右客户端页面输出的总耗时大约 17.6秒除去代理服务准备数据的时间代理服务和客户端之间传输数据消耗了大概11秒左右--------------------1号方案测试结果我们在Web服务器上面监视直接使用ADO.NET查询数据所要的时间具体代码如下[WebMethod]public DataSet GetALLUser(){System.Diagnostics.Stopwatch timer new System.Diagnostics.Stopwatch();timer.Start();string sql select top 100000 * from B_User where UID not in (select top 2000000 UID from [B_User]);DataSet ds new DataSet();SqlDataAdapter ada new SqlDataAdapter(sql, conn);ada.Fill(ds);timer.Stop();System.Diagnostics.Debug.WriteLine(WebService 耗时(毫秒)timer .Elapsed .TotalMilliseconds);return ds;}执行该程序的时间为WebService 耗时(毫秒)3339.8151而整个执行时间从客户端发起请求到完成数据绑定一共耗时大约12.5秒也就是Web服务和客户端的数据传输时间大概9.2秒----------------------综合对比结果1号方案胜出比2号方案快大约 5秒JSON 输给了XML------------------------------我们看看1号方案和2号方案在数据传递过程的路线1号方案数据库》Web服务》客户端2号方案数据库》外围服务》代理服务》客户端从数据传输路径来说2号方案明显比1号方案多了一个“代理”环节自然有人怀疑这样的方案数据查询会不会超时但我们仔细分析2号方案在“分布式数据查询”方面没有输给1号方案的“集中式数据查询”我们看到如果1号方案的服务器环境完全一致代理服务拿数据的时间大约在3.5秒左右除去耗时的50.5服务器而Web服务上面取数据也要3.3秒左右这两种方式的数据查询效率差异基本上可以忽略但为啥2号方案的最终结果跟1号方案差距 有5秒排除较慢的50.5服务器也有2秒之多呢方案2不是使用了JSON来传递数据吗按照一般的理解JSON格式的数据量比XML格式的数据量要小的一般也会节约至少15%左右的数据量未做过仔细测试所以JSON格式的数据应该比XML快但这里JSON却输给了XMLJSON不堪 “序列化”/“反序列化”之重-----------------------------------------我们的测试环境中客户端都是ASP.NET后台程序没有在前台用IE直接使用Ajax测试因为HTML表格直接绑定XML格式的数据比较困难所以我们的“客户端”程序是一个ASP.NET后台程序来分别绑定1号方案的DataSet和2号方案的实体类的但问题也在这里。DataSet的数据表示天生就是直接支持XML的所以它在后台系统间传输数据“序列化”/“反序列化”非常快在此我不敢肯定是不是这样对.NET底层不是很了解而实体类要表示成JSON格式必须序列化在前台这里的客户端必须对JSON字节流反序列化再生成实体类这一过程通过上面的对比我们发现效率是很低的因为2号方案只有4台服务器工作故实际上查询的总数据量比1号方案少了2万条。下面附上JSON在前台反序列化的代码/// summary/// 以GET方式请求WCF服务并将结果处理成指定的类型。服务端采用JSON格式处理请求和返回值。/// /summary/// typeparam nameTResult结果类型/typeparam/// param nameurl服务地址例如请求一个带参数的方法 http://localhost:9162/Service1.svc/GetData?value10 /param/// returns返回 TResult 类型的数据/returnspublic static TResult GetDataTResult(string url) where TResult : class{var request GetRequest(url, GET);var stream request.GetResponse().GetResponseStream();DateTime dt DateTime.Now;var serializer new DataContractJsonSerializer(typeof(TResult));var result (TResult)serializer.ReadObject(stream);System.Diagnostics.Debug.WriteLine(DataContractJsonSerializer use time(ms): DateTime.Now.Subtract(dt).TotalMilliseconds);return result;}private static System.Net.WebRequest GetRequest(string url, string method){if (url null || url.Trim().Length 0)throw new ArgumentNullException(服务地址为空参数url);var request System.Net.WebRequest.Create(url);if (method ! null method.Trim().Length 0)request.Method method;return request;}