WCF 消息压缩性能问题及解决方法
2013-08-20 16:51
183 查看
WCF 消息压缩性能问题及解决方法
最近使用WCF作为通迅框架开发一套信息系统,系统使用传统C/S框架,系统有可能会部署在互联网上,因此决定对传输的数据进行GZIP压缩,原来在使用.NET Remoting时,可以使用插入自定义的ChannelSink来实现数据压缩,作为.NET Remoting的替代方案的WCF,实现起来也很容易,且方法不止一种,主要解决方法主要有以下四种:
通过自定义MessageEncoder和MessageEncodingBindingElement 来完成。具体的实现,可以参阅张玉彬的文章《WCF进阶:将编码后的字节流压缩传输》和MSDN的文章《Custom Message Encoder: Compression Encoder》。
直接创建用于压缩和解压缩的信道,在CodePlex中具有这么一个WCF Extensions;
自定义MessageFormatter实现序列化后的压缩和反序列化前的解压,详见WCF大师Artech中的博客有《通过WCF扩展实现消息压缩》
自定义MessageInspector实现这就是我们今天将要讨论的解决方案。
相比较,第三和第四实现相对简单,配置很简单,它们的内部实现方法很类似,我的消息压缩类也来源于WCF大师Artech的博客《通过WCF扩展实现消息压缩》的消息压缩类,区别在于第三在自定义MessageFormatter中对消息进行压缩和解压缩,而第四是在自定义MessageInspector中对消息进行压缩和解压缩。下面给出第四种实现方法(网络上也很多):
一、Compress-压缩与解压缩类
压缩与解压缩类
消息压缩与解压缩类
客户端对消息进行压缩与解压缩的消息检查器
客户端用于插入压缩消息检查器的终节点行为器
服务端对消息进行压缩与解压缩的消息检查器
服务端用于插入压缩消息检查器和服务端行为器
五、服务端配置
在system.serviceModel节点下添加:
好了,上面的基本的实现,可以通过在客户端行为器中添加AcceptEncoding=gzip的消息头来确定服务端返回的消息是否也可以(需要)进行压缩,实际运行结果也正常,但后来发现在进行大量byte[]类型数据传输时,发现有延时,几百K有数据,在局域网(排除网络问题)内,尽然达到2秒左右延时,开始怀疑的GZIP压缩类有问题,后发现,压缩类的对数据进行压缩时,耗时极小,一般几毫秒到几十毫秒之间,最后,只能逐语句进行排查,发现问题在消息压缩类中的:
Message在经过每一层消息检查器时,都是以Message方法进行传递,只有到达TransportBinding上编码器时,才会对Message进行编码,或文本,或二进制,但在我上面的消息压缩中,先从原Message中获取Body内容,然后对Body进行压缩,再把压缩Body封装进新的Message中,问题就出在获取Body内容中,XmlDictionaryReader 的ReadOuterXml()方法相当对Body进行了XML的编码,所以导致了性能问题。解决问题的根本在于找到一个能获取到Body内容,又能避免提前对Body内容进行XML编码的方法。
将上述代码改为以下代码后,性能得以大幅提升:
但最终获取到的buffer是一致的,是什么原因导致它们之间有巨大的性能差异就不得而知了……
最近使用WCF作为通迅框架开发一套信息系统,系统使用传统C/S框架,系统有可能会部署在互联网上,因此决定对传输的数据进行GZIP压缩,原来在使用.NET Remoting时,可以使用插入自定义的ChannelSink来实现数据压缩,作为.NET Remoting的替代方案的WCF,实现起来也很容易,且方法不止一种,主要解决方法主要有以下四种:
通过自定义MessageEncoder和MessageEncodingBindingElement 来完成。具体的实现,可以参阅张玉彬的文章《WCF进阶:将编码后的字节流压缩传输》和MSDN的文章《Custom Message Encoder: Compression Encoder》。
直接创建用于压缩和解压缩的信道,在CodePlex中具有这么一个WCF Extensions;
自定义MessageFormatter实现序列化后的压缩和反序列化前的解压,详见WCF大师Artech中的博客有《通过WCF扩展实现消息压缩》
自定义MessageInspector实现这就是我们今天将要讨论的解决方案。
相比较,第三和第四实现相对简单,配置很简单,它们的内部实现方法很类似,我的消息压缩类也来源于WCF大师Artech的博客《通过WCF扩展实现消息压缩》的消息压缩类,区别在于第三在自定义MessageFormatter中对消息进行压缩和解压缩,而第四是在自定义MessageInspector中对消息进行压缩和解压缩。下面给出第四种实现方法(网络上也很多):
一、Compress-压缩与解压缩类
压缩与解压缩类
消息压缩与解压缩类
客户端对消息进行压缩与解压缩的消息检查器
客户端用于插入压缩消息检查器的终节点行为器
服务端对消息进行压缩与解压缩的消息检查器
服务端用于插入压缩消息检查器和服务端行为器
五、服务端配置
在system.serviceModel节点下添加:
<extensions> <behaviorExtensions> <add name="compressBehavior" type="ServiceCompressBehavior, Service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions>
<behaviors> <serviceBehaviors> <behavior> <compressBehavior /> </behavior> </serviceBehaviors> </behaviors>
好了,上面的基本的实现,可以通过在客户端行为器中添加AcceptEncoding=gzip的消息头来确定服务端返回的消息是否也可以(需要)进行压缩,实际运行结果也正常,但后来发现在进行大量byte[]类型数据传输时,发现有延时,几百K有数据,在局域网(排除网络问题)内,尽然达到2秒左右延时,开始怀疑的GZIP压缩类有问题,后发现,压缩类的对数据进行压缩时,耗时极小,一般几毫秒到几十毫秒之间,最后,只能逐语句进行排查,发现问题在消息压缩类中的:
using (XmlDictionaryReader reader1 = sourceMessage.GetReaderAtBodyContents()) { sourceBody = reader1.ReadOuterXml(); buffer = Encoding.UTF8.GetBytes(sourceBody); }
Message在经过每一层消息检查器时,都是以Message方法进行传递,只有到达TransportBinding上编码器时,才会对Message进行编码,或文本,或二进制,但在我上面的消息压缩中,先从原Message中获取Body内容,然后对Body进行压缩,再把压缩Body封装进新的Message中,问题就出在获取Body内容中,XmlDictionaryReader 的ReadOuterXml()方法相当对Body进行了XML的编码,所以导致了性能问题。解决问题的根本在于找到一个能获取到Body内容,又能避免提前对Body内容进行XML编码的方法。
将上述代码改为以下代码后,性能得以大幅提升:
MemoryStream ms = new MemoryStream(); XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(ms, Encoding.UTF8); sourceMessage.WriteBodyContents(writer); writer.Flush(); buffer=ms.ToArray();
但最终获取到的buffer是一致的,是什么原因导致它们之间有巨大的性能差异就不得而知了……
相关文章推荐
- WCF 消息压缩性能问题及解决方法
- IIS启用Gzip压缩造成OpenFlashChart不能正常显示问题及解决方法
- Redis 常见的性能问题和解决方法
- SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法
- Unity 中关于中文乱码以及压缩解压遇到的问题解决方法
- WCF 部署问题 小总结 (HTTP 不能注册的解决方法)
- SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法
- J2EE系统应用性能问题解决的通用方法
- 关于图片预览使用base64在chrome上的性能问题解决方法
- SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法【已验证】
- SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法
- 推荐Sql server一些常见性能问题的解决方法
- Redis 常见的性能问题和解决方法
- WCF已超过传入消息(65536)的最大消息大小配额的解决方法
- 三个方面解决性能问题的基本思路和方法(微信读书-ios-姚海波;整理:Kiwi)
- 在类库中创建WCF的引用问题解决方法
- 参照msdn学习 wcf ria services 的过程中碰到的问题及解决方法
- android开发游记:位图压缩技巧与方法总结,解决加载大图内存占用过大问题
- win7系统音量QQ来消息声音突然变小问题的解决方法
- Redis 常见的性能问题和解决方法