【问题标题】:WCF + Gzip Performance IssuesWCF + Gzip 性能问题
【发布时间】:2011-08-01 08:19:51
【问题描述】:

我有一个 WCF 服务,它返回内容类型“application/x-gzip”,它本质上似乎是使用 Gzip 压缩的 XML/Json。我实现了 GzipMessageEncoder 和 CustomBinding,如下面的 Carlos Figueira 链接所述:

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/8c3eafae-b6a1-441f-85ef-90721d941a1a

对于我的服务返回的数据,我使用带有 JSON 的基本网格概念,它拆分架构并为每一行使用字符串 [] 以保持紧凑:

[DataContract]
[KnownType(typeof(JsonContract))]
[KnownType(typeof(ColumnDefinition))]
public class JsonContract
{
    [DataMember]
    public List<ColumnDefinition> Schema { get; set; }

    [DataMember]
    public List<String[]> Rows { get; set; }
}

public class Service : IGzipTest
{
    public JsonContract HttpRequest() 
    {
        // return json data
    }
}

Gzip 工作正常,但我认为我的客户端的性能很慢/不一致,使用 ChannelFactory:

    private ChannelFactory<T> CreateFactory<T>(CustomBinding binding, string endpoint)
    {
        EndpointAddress _endpoint = new EndpointAddress(endpoint);
        ChannelFactory<T> _factory = new ChannelFactory<T>(binding, _endpoint);

        _factory.Endpoint.Behaviors.Add(new WebHttpBehavior());

        return _factory;
    }

这是我启动服务的方式:

    static string baseAddress = "http://" + Dns.GetHostName() + ":4050/ZipTest";
    static ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));

    protected void Application_Start(object sender, EventArgs e)
    {
        ThreadPool.SetMinThreads(Environment.ProcessorCount, 9); 

        host.AddServiceEndpoint(typeof(IGzipTest), 
            GzipMapper.GetBinding(), "").Behaviors.Add(new WebHttpBehavior()); 

        host.Open();
    }

当下载 ~512kb 到 ~1mb 的数据(压缩后)时,这些是我在单独的连续测试中的性能结果:

   1st Request: 4439ms
   2nd Request: 19029ms

   ..and so on

似乎每隔一次调用该服务需要大约 4-5 倍的时间。对于 512kb 到 1mb 的数据,即使 4000 毫秒似乎也很长,所以我想知道可能出了什么问题。

例如,如果我使用 [WebGet] 修饰方法从浏览器下载 .gz 文件本身,最多只需要一秒钟,因为我最差的速度是 400-500kb/s。

【问题讨论】:

    标签: c# wcf performance gzip channelfactory


    【解决方案1】:

    我已经看到了类似的波动,至少这是我目前的想法,它们是由 GzipMessageEncoder 和缓冲的 TransferMode(这是默认设置)的过多内存使用引起的。 Buffered TransferMode 使用 BufferManagers,这可能会导致严重的内存问题并导致 OutOfMemoryExceptions。

    不管具体原因是什么,我都解决了这个问题,并且大大减少了服务器和客户端的内存消耗和 CPU 负载

    1. 摆脱 GzipMessageEncoder,见wcf conditional compression
    2. 更改为流传输模式,请参阅How can I prevent BufferManager / PooledBufferManager in my WCF client app from wasting memory?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-09
      • 2011-01-07
      • 2012-11-02
      相关资源
      最近更新 更多