Small web service benchmark
I am trying to develop a small application that checks how many requests per second my service can support, but I think I am doing something wrong. The service is in early stages of development, but I would like this test to be handy to check from time to time that I am not doing something that slows down performance. The problem is I can't get the webserver or database server to go 100% CPU.
I am using three different computers, one is a web server (WinSrv Standard 2008 x64 IIS7), another database (Win 2K, SQL Server 2005), and the last one is my computer (Win7 x64 Ultimate) where I will run the test. The computers are connected via an Ethernet network switch. The POST request is 9 bytes and the response will be 842 bytes.
The test runs multiple threads, and each thread has a loop while
, in each loop it creates an object WebRequest
, makes a call, increments the total counter and waits for 1 to 5 milliseconds, then it does it again:
static int counter = 0;
static void Main(string[] args)
{
ServicePointManager.DefaultConnectionLimit = 250;
Console.WriteLine("Ready. Press any key...");
Console.ReadKey();
Console.WriteLine("Running...");
string localhost = "localhost";
string linuxmono = "192.168.1.74";
string server = "192.168.1.5:8080";
DateTime start = DateTime.Now;
Random r = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < 50; i++)
{
new Thread(new ParameterizedThreadStart(Test)).Start(server);
Thread.Sleep(r.Next(1, 3));
}
Thread.Sleep(2000);
while (true)
{
Console.WriteLine("Request per second :"
+ counter / DateTime.Now.Subtract(start).TotalSeconds);
Thread.Sleep(3000);
}
}
public static void Test(object ip)
{
Guid guid = Guid.NewGuid();
Random r = new Random(DateTime.Now.Millisecond);
while (true)
{
String test = "<lalala/>";
WebRequest req = WebRequest.Create("http://"
+ (string) ip + "/WebApp/" + guid.ToString()
+ "/Data/Tables=whatever");
req.Method = "POST";
req.ContentType = "application/xml";
req.Credentials = new NetworkCredential("aaa", "aaa","domain");
byte[] array = Encoding.UTF8.GetBytes(test);
req.ContentLength = array.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(array, 0, array.Length);
reqStream.Close();
}
using (Stream responseStream = req.GetResponse().GetResponseStream())
{
String response = new StreamReader(responseStream).ReadToEnd();
if (response.Length != 842) Console.Write(" EEEE ");
}
Interlocked.Increment(ref counter);
Thread.Sleep(r.Next(1,5));
}
}
If I run the test, none of the computers are using excessive CPU usage. Let's say I get X requests per second, if I run the console app twice at the same moment, I get X / 2 requests per second in each of them ... but still the webserver is at 30% from CPU, database server at 25% ...
I tried deleting Thread.Sleep
in a loop, but it doesn't really matter.
I would like to put the machines at maximum to test how they can query per second they can provide. I guessed that I could do it this way ... but apparently I am missing something here ... What is the problem?
Sincerely.
source to share
There are many restrictions besides the CPU on the web server. There are many IIS settings that can suppress the number of connections.
I would read this:
http://www.eggheadcafe.com/articles/20050613.asp
I know this is for IIS 6, but there are things that will still apply.
If you have access to MSDN and have VS 2010 I would check out their load testing tools. It can be expensive to purchase a load testing program, but if you need to test something specific, you can use the trial version to accomplish what you need. You can use it for monitoring and response times, server usage, etc. Well worth a look.
source to share
IMO you are better off using SoapUI for the test. You can easily set up a test case for the number of threads, the number of iterations, etc. And it will display the results. When you hit a plateau where you are overloading the server, you will see it on the graph. If one PC isn't enough, just run them on other PCs. You can do it all with the free version.
source to share