分布式计算,WCF+JSON+实体对象与WebService+DataSet效率大比拼

最近做公司项目,我们要整合所有业务系统的客户数据,各业务系统的数据库有的Oracle,有的是SQLSERVER,而且表结构也不相同,如何整合不同系统之间的客户数据成为一个令人头痛的难题!

解决方案:

在整合数据的方式上存在分歧,有两种方案:

方案1,将所有系统的客户数据整合到一个数据库中--“中心数据库”,所要的工作主要有设计一个“超级客户数据表”,尽可能多的包含各个业务系统的客户数据表的字段,然后再开发一套程序完成各个业务数据库与“中心”数据库直接的数据导入,更新,同步等;

方案2,不设立“中心数据库”,数据从各个业务系统中按需查询,在内存中整合查询出的部分数据为一个内存数据集,数据集的表头根据配置决定,所需要的工作相对复杂,需要在各个业务系统中开发和部署“客户数据服务”,还要开发一个代理服务来整合数据,好处是方案1的数据更新同步问题不存在了,数据维护量大大减轻。

我们采用WCF服务来实现2号方案,具体来说就是在各个业务系统中开发各自的WCF客户数据服务(以下简称外围服务),再开发一个整合数据的WCF代理服务,在外围服务和代理之间使用TCP通道进行数据的高速传输,而在客户端和代理服务端,为了让IE这样的客户端能够使用JSON格式的数据,所以我们在代理服务端采用WCF+JSON+实体类 的方式提供服务。

经过长达半个月的可行性测试开发(POC程序),方案2终于成功实现了,但公司其它同事对这样的“分布式计算”模式很是怀疑,因为以前从没有人这么做过,况且公司是以做数据起家的,对“集中式数据管理”的优势深信不疑,要求我们搭建一个测试环境进行对比测试。

测试环境:

2号方案测试环境:

有5台服务器,A,B,C,D,E,在每台服务器上面部署一个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 已经成功完成任务,距离开始时间(ms):2633.1506 线程 0x1550 已退出,返回值为 0 (0x0)。 2010/7/7 16:02:56 服务器192.168.50.19:8119 已经成功完成任务,距离开始时间(ms):3180.1819 线程 0x160c 已退出,返回值为 0 (0x0)。 2010/7/7 16:02:56 服务器192.168.50.15:8119 已经成功完成任务,距离开始时间(ms):3457.1978 线程 0x8c0 已退出,返回值为 0 (0x0)。 2010/7/7 16:02:59 服务器192.168.50.5:8119 已经成功完成任务,距离开始时间(ms):6033.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却输给了XML?

JSON:不堪 “序列化”/“反序列化”之重!

-----------------------------------------

我们的测试环境中,客户端都是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 name="TResult">结果类型</typeparam>
        /// <param name="url">服务地址,例如请求一个带参数的方法 http://localhost:9162/Service1.svc/GetData?value=10 </param>
        /// <returns>返回 TResult 类型的数据</returns>
        public static TResult GetData<TResult>(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;
        }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程直播室

魅族手机调试和VID一、 现象:二、 原因三、 解决方法:四、 其它手机类似问题处理:五、科普VID:

28530
来自专栏北京马哥教育

服务器病了吗? Linux 服务器的那些性能参数指标

30720
来自专栏张善友的专栏

K2 blackpearl 中的业务规则(Rules)

在K2流程系统中,流程中的任何一个执行节点(一个节点可以包含多个事件)都可能包含客户端事件,服务器端事件,以及子流程(IPC,Inter Process Com...

20170
来自专栏小特工作室

工作流组件示例(全部开源)

1.概述 1.1简介 本文档旨在帮助开发人员快速使用工作流组件,完成OA或审批等涉及到工作流组件的系统开发工作 1.2组件构成 1.2.1组件层次图 ? 组...

784100
来自专栏FreeBuf

滥用Edge浏览器的“恶意站点警告”特性,实现地址栏欺骗

前言 在过去的几个月里,我们看到使用这种以技术支撑的骗术日益增多,用户的浏览器会被辣眼睛的红屏以及类似”你的电脑可能存在风险”的提示消息”锁定”。当然,这种情形...

25290
来自专栏架构师之旅

关于Socket高并发的原理介绍及使用Apache Mina带来线上的问题分析

上周在线上出现了一个很低级的问题,但是正是这个低级的问题引起了我的兴趣,其实所谓的低级是因为配置文件配置错了,原本线上是为每个客户端设置了一个席位,就说是客户端...

39430
来自专栏IT大咖说

vSAN架构解析与6.7功能介绍

内容来源:2018 年 7 月 17 日,VMware大中华区原厂高级技术讲师史峻在“VMware直播分享 第二期”进行《vSAN架构解析与6.7功能介绍》演讲...

33530
来自专栏Pythonista

python多线程与线程

考虑一个场景:浏览器,网易云音乐以及notepad++ 三个软件只能顺序执行是怎样一种场景呢?另外,假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大...

19720
来自专栏猫哥学前班

猫哥网络编程系列:HTTP PEM 万能调试法

注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新。 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么...

41360
来自专栏IT大咖说

VMware vSAN 架构解析及存储策略

摘要 VMware vSAN 通过 vSphere 原生的高性能体系结构支持业界领先的超融合基础架构解决方案。 vSAN是 Software-Defined D...

56030

扫码关注云+社区

领取腾讯云代金券