WCF + Gzip Performance Issues
Ive got a WCF service that returns content-type 'application/x-gzip' which essentially appears to be XML/Json that is compressed using Gzip. I implemented a GzipMessageEncoder and CustomBinding as described at the following link by Carlos Figueira:
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/8c3eafae-b6a1-441f-85ef-90721d941a1a
For the data that my service returns I'm using a basic grid concept w/ JSON that splits up the schema and uses a string[] for each row to keep things compact:
[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
}
}
The Gzip is working fine but I think the performance on my client is slow / inconsistent, using 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;
}
Here is how I start the service:
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.ProcessorC开发者_如何转开发ount, 9);
host.AddServiceEndpoint(typeof(IGzipTest),
GzipMapper.GetBinding(), "").Behaviors.Add(new WebHttpBehavior());
host.Open();
}
When downloading ~512kb to ~1mb of data (thats after compression), these are my performance results on seperate consecutive tests:
1st Request: 4439ms
2nd Request: 19029ms
..and so on
It seems that every other call to the service takes about 4-5 times as long. Even 4000 ms seems long for only 512kb to 1mb of data, so I'm wondering what could be wrong.
For instance if I download the .gz file itself from a browser using a [WebGet] decorated method it only takes a second at most because I am hitting 400-500kb/s at worst.
I have seen similar fluctuations, and they were caused, at least that's what I'm currently thinking, by excessive memory use of GzipMessageEncoder and buffered TransferMode, which is the default. Buffered TransferMode uses BufferManagers, which can lead to severe memory issues and were causing OutOfMemoryExceptions for me.
Whatever the exact reasons, I fixed that and also vastly reduced memory consumption and cpu load of both servers and clients by
- Getting rid of GzipMessageEncoder, see wcf conditional compression
- Changing to streamed TransferMode, see How can I prevent BufferManager / PooledBufferManager in my WCF client app from wasting memory?
精彩评论