0

我有一个 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 的基本网格概念,它拆分模式并为每一行使用 string[] 以保持紧凑:

[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 倍的时间。即使 4000 毫秒似乎只有 512kb 到 1mb 的数据,所以我想知道可能出了什么问题。

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

4

1 回答 1

2

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

不管具体原因是什么,我都修复了这个问题,并通过以下方式大大减少了服务器和客户端的内存消耗和 CPU 负载

  1. 摆脱 GzipMessageEncoder,见wcf 条件压缩
  2. 更改为流传输模式,请参阅如何防止 WCF 客户端应用程序中的 BufferManager / PooledBufferManager 浪费内存?
于 2011-09-02T01:57:46.823 回答