6

I have simple ASP.NET application which just resizes images with ImageResizer and does nothing else. For testing purposes I disabled disk caching, so images are resized on every request.

When I test performance of the app with JMeter I get the following average response times:

  • single worker process, 1 concurrent clients: ~200ms
  • single worker process, 10 concurrent clients: ~1200ms
  • 4 worker processes, 10 concurrent clients: ~300ms

As you can see, when I run single worker process and 10 concurrent clients, response time increases dramatically despite of available hardware resources: CPU usage during performance test is ~30%, memory usage is ~150MB.

As discussed here,

Web gardens was designed for one single reason – Offering applications that are not CPU-bound but execute long running requests the ability to scale and not use up all threads available in the worker process.

This not seems as my case.

I don't understand why I get such result. What I expect is that even single worker process would provide acceptable response time until it reaches resources limits. And 10 concurrent clients are definitely not a heavy load. Can somebody explain to me, where am I wrong?

My configuration:

  • Windows Server 2012 R2
  • IIS 8.5 with all default settings (except MaxWorkerThreads)
  • quad-core i3 3.4GHz CPU
  • 16 GB RAM

My application is just empty ASP.NET MVC application with ImageResizer, added as in this instruction (option 3 - Manual Installation) and with DiskCache plugin disabled in Web.config

Marat Safin
  • 1,793
  • 20
  • 28
  • 1
    Just based on those numbers you provided, and without knowing anything about ImageResizer, it looks like ImageResizer is running resize operations in a single thread, maybe the STA? This (speculation) might be the case if it was based on a COM component which didn't support multiple threads. – Ben Jan 02 '17 at 14:59

1 Answers1

4

I found an answer thanks to @Ben's comment.

The problem is ImageResizer is based on GDI+ (as stated on it's site), which contains locks inside (see this and this posts for details). This is why it works so slowly in single process.

After finding the cause of problem I tried this solution. Referencing WPF assemblies from ASP.NET application is, probably, not a best idea, but it's ok for testing purposes.

Now I get the following results when I perform the same performance testing as in question:

  • single worker process, 1 concurrent client: ~90ms
  • single worker process, 10 concurrent clients: ~120ms
  • single worker process, 40 concurrent clients: ~190ms
  • single worker process, 60 concurrent clients: ~400ms
  • single worker process, 80 concurrent clients: ~630ms

As you can see, now application works much faster. Also it utilizes almost all available CPU resources under high load, as I expected initially.

So, if you process images in your ASP.NET application:

  • don't use GDI+ based solution, if you can
  • if you have to use GDI+, increase MaxWorkerProcesses in applicaion pool's settings
Community
  • 1
  • 1
Marat Safin
  • 1,793
  • 20
  • 28
  • So what about two+ worker processes with the new code? – Simon_Weaver Aug 26 '18 at 07:38
  • 1
    As far as I remember, there wasn't any difference between single and multiple worker processes with the new code: in both cases application has been scaling up without problems until reaching hardware resources limits. – Marat Safin Aug 26 '18 at 09:32