I'm trying to run some load tests for a web application hosted on IIS using Visual Studio 2012.
Testing for several hundred users works fine (but isn't too helpful).
When I try raising the number to 1000+, the test fail;
But not because the website can't handle the load --- it's because my computer won't handle it!
Is there any way to test for large amounts of users, without crashing my own computer?
Distributed load tests are a better bet in several ways. In addition to not overwhelming your computer, they better simulate traffic from different locations, whether around the country or around the world. You get a better picture of how actual traffic can affect your site response.
I haven't done load testing from Visual Studio, but it should be possible to hit your site (assuming it's on one or more servers, and not also running locally) from multiple computers running VS. Alternately, you might want to look into load testing services, such as from SOASTA, that run load tests from the cloud.
Some commercial load testing tools also allow for distributed load testing. Disclaimer: I work for Telerik in the Test Studio group, and we have distributed load testing.
Jacob,
It sounds like you're overloading your system. With any significant load run, regardless of the toolset, you need to get the various load components distributed out to run on different systems.
If you haven't already, you should have a look at the Working With Load Tests documentation on MSDN. See also the Considerations for Large Load Tests (especially the part about overloading Agents) as well as the Run a Load Test Using Agents pages.
Related
I'm a teacher in a training center for web development. We're teaching PHP and Node.js for the backend. In this context, it's very cool to allow our students to deploy small web servers. Unfortunately paying for one VPS per student ain't cheap, and free web hosting solutions are usually too limited.
That's why we go for the shared hosting route with unused computers, Raspberry-pis or small VPSs and create an account for each student.
With PHP it's easy. People do a shared hosting with PHP since decades and there's basically a complete feature in Apache to do that super easily (per-user web directories). We just add some shared database, script the initialization of users and we're ready to go.
For node.js... it's another story. No one seems to care about shared hosting in that community and everyone just pops a new VPS for each application or make a manual configuration with root access on a custom server.
To allow somewhat secure solution for automatic shared hosting with Node.js I would need some kind of application server that could:
Read through user directories (or multiple directories based on a pattern) for some source JavaScript files to execute.
Launch different applications with different users (for security purposes).
Kill and restart applications depending on incoming requests and usage of RAM (you can't launch simultaneously 30 node.js apps that consume 30 Mb of RAM minimum on a VPS with 512Mb or Ram, no you can't)
Monitor the node.js applications in order to avoid crashes if one of them does something bad (purposely or not, we're talking about web dev students... :) )
Theorically I know some web servers that could potentially be configured to do that (uWsgi and Passenger are the first that come to my mind). But I fear I could take multiple hours or days trying to alter their default behavior before realizing that I just set up a crappy solution that will crash after two days in production.
So... does anyone has some kind of solution for that use case? I'm open to anything, even Docker-based solutions. Just remember the three magic words: security, security and security. We just can't allow anyone to have root accounts on a server we own or to make it crash by too much consuming RAM or CPU.
Thanks in advance for your answers.
i have successfully run the load test but i am getting too much threshold violation, what is the reason for it And how to reduce the threshold violation.
Threshold violation say that the named computer(s) are close to being overloaded.
If the named computer(s) are the computers running the tests then you should consider spreading the load using controllers and agents, or using more powerful computers. In this case the load test may be reporting, or close to reporting, incorrect results because it is on the verge of being overloaded.
If the named computer(s) are the servers in the system being tested then the violations show that the servers are close to their limit and will not support many more virtual users. In this case the performance test has found a limitation of the system under test.
Is it possible to create one or several azure VMs on my local machine? I want to create a web app and load test it locally, without the need of putting it in the cloud. I'm thinking at the following scenario: I have a local VM running a IIS server with my web app; I use a tool to generate a lot of load; I need to deploy the second VM containing the same things as the first VM. The downtime of the web app should be equal to 0(hopefully).
Clarification(update):
I want to achieve the following: create a web app and a monitoring app(CPU,Memory) and deploy them on one VM. On a load test, if the VM cannot handle it(e.g. CPU goes above 80%), I want to programmatically deploy a new VM(with the same configuration, having both the web app and the monitoring app), such that no downtime occurs.
Azure has several ways for you to host sites.
Virtual Machines is just that, normal VMs. You can create them locally and upload them, but everything is up to you, including how to handle upgrades. If that is what you need to do then I don't know how you would handle upgrades with no down time; though, you can add multiple VMs to a load balancer and then upgrade them one at a time.
It sounds like what you really want to explore is Cloud Services. You can run one or more VMs locally in the emulator, upgrade with no down time once in the cloud, implement auto scaling (you will have to use a tool or write some code).
Alternatively you may want to look at Azure Web sites, but that is a completely different concept and you can't really test load and load balancing locally the same way.
Based on your statement that you essentially want to auto-scale your application you want to look at Cloud Services with Auto Scaling. However, you can't fully test this in the cloud emulator - but you can test your logic.
Background
Azure Cloud Services is designed for this kind of thing; You don't really work with VMs in the way you may be used to, instead you create a package that Azure then deploys to as many servers as you like. Once up and running, you can manually go into the management console and increase or decrease the number of active servers simply by moving a slider. Of course, you want to do this automatically, so you have a few options.
There is a management API you can use to change the number of servers. So, it would be quite simple to write a bit of code that you spin up in another thread from WebRole.Start and that simply sits and monitors the CPU on the machine and then calls the management API to spin up a new server instance if your CPU goes over a certain treshold. Okay, locally you can only test that the call to the management API is made, you won't actually see the new server coming up. But, if you grab your free trial of Azure and just try it you will see that you really don't need to test that part - it just works.
However, in practice there is an awful lot more to auto scaling. Here are some of the things you need to consider;
Even relatively idle web servers will often spike briefly to 100% so just having a simple treshold is unlikely to be good enough; You need to decide on how long the server needs to be over a certain treshold before you spin up another server instance.
What happens when you have more than one server? And, on Azure, you should always have at least two servers to ensure you have resilience. Note that the idea with Cloud Services really is to have many small servers rather than a few big servers. You pay per core, not per number of servers.
Imagine you currently have three servers and one is really busy for some reason and the other two are idle. Do you want to spin up a fourth server?
Imagine you currently have two servers and they are both quite busy. Do you really want them both to start a new server so you end up with four servers running?
There are several ways to handle these challenges. For starters, rather than having monitor programs running locally on each server, you are better of moving that monitoring outside; Azure comes with the ability to dump performance metrics to table storage at whatever interval you choose. You can then run an external program that retrieves the performance data over time from all your current servers and then reason about the overall workload before deciding to spin up or shut down additional servers. Now, you can of course host that external monitor program in a separate thread on each of your webroles to give your monitoring resilience - but the key point is that the monitoring program doesn't monitor the server it runs on, it monitors all the servers. You will, of course, still have to deal with stopping multiple monitoring program instances from all starting and stopping servers. One way to do is to place stop/start commands onto an Azure "message queue" (there are a few different types) and use the built-in "de-duper" which will automatically delete identical commands that are put on the queue within a certain time window (I am over simplyfing but you get the idea).
The actual answer
Really, though, you want to look at the Auto Scaling Application Block which will do most of this for you. I guess that is the real answer to your question, but I wanted to provide a bit of context first.
Again, I recognise you asked for how to test this locally - but I believe that that question doesn't really make sense in the context of Azure and I hope the above information helps.
I'm pretty sure you can't do that and it wouldn't make sense anyway. If you want load testing, you need to run that in an environment as similar to production as possible and that means you have to run your application is Azure cloud. How else do you know that the load will actually be processed fine on real cloud?
For eaach BizTalk application we have a setup.bat, which creates the BizTalk application, creates file drops, build code, gacs, registers resources, creates ports -using vcscripts- and applies bindings. We also have a cleanup.bat which performs the opposite of setup.bat
These scripts are then run via nant, and finally used by cruisecontrol.net. These scripts allow us to setup a BizTalk app on a machine with BizTalk and the latest source and tools downloaded.
What do others do to "bootstrap" BizTalk applications in a repeatable and automated manner ?
I've seen BizTalk nant tasks, are they faster than vbscript ?
The setup. bat runs slower on our BizTalk build machine by a factor of about 3 ! Disk, CPU, Memory, paging are all comfortable. A full build/deploy is taking 2 hours before any tests have run - have about 20 BizTalk apps and assorted C# services, custom components. Aside from a new machine, or rebuild - our build machine has 4 gig ram, dual hyper threaded cores and about 5 years old server- Any ideas ? What are you build machines like.
Michael Stephenson has written some great blogs on automated BizTalk builds, take a look at link text
We have used a utility which Mike posted to codeplex which will create an MS build script for a BizTalk application - this has worked very well for us. You can find this at link text
We use NAnt as well for our BizTalk deployment. Specifically, we use a combination of calling the BizTalk related NAntContrib tasks (which all begin with bts) and using the <exec> task to call the command line btstask.exe directly.
At some level, they are all using the same underlying technology to talk to the BizTalk server, so it's hard to say whether NAnt is faster than something like VB.
I will say that in my experience BizTalk appears to be a resource hog. Since it's hard to change that, the only thing we do have control over is the amount of resources we give it. Therefore, if builds are taking too long, and one has the time/money to do so, throw bigger and badder hardware at it. This is generally the cheapest way as the amount of time us developers put into making sub-marginal improvements to build times can end up costing way more than hardware. For example, we've noticed that moving to 8GB of memory can make all the difference, literally transforming the entire experience.
I just create an MSI through the BizTalk Administrator. I keep my binding information separate from the MSI, so developers need to bind ports by importing the binding files, but that is easy.
In cases where assemblies need to be deployed into the gac, I use a batch file that runs gacutil, then install the MSI and finally bind the ports.
This approach is easy to maintain and, more importantly, easy for others to understand and troubleshoot.
In regards to BizTalk being a resource hog, first look at SQL Server and make sure that you limit it to some reasonable amount of memory (it takes whatever it can by default - which is usually most available memory). That one change alone makes a significant difference.
You should also consider using only minimal software during development - that means disabling the anti-virus or excluding directories from getting uselessly scanned when developers compile and deploy. Avoid using MS Word, Messenger, etc on systems that have little RAM (2Gb or less) while developing a BizTalk solution.
On developers' workstations, enable the BizTalk messagebox archive and purge job as explained here:
http://msdn.microsoft.com/en-us/library/aa560754.aspx
Keeping the database small saves valuable disk space which can help to improve overall performance.
There are quite a few solutions out there -
Rob Bowman mentioned Michael Stephenson's msbuild generator
Also on codeplex you can find another framework by Scott Colestock,Thomas Abraham and Tim Rayburn
There's also a minor addition by me palying with Oslo, but that's not half as mature as these two, but it does use the SDC tasks, which is a great starting point if you wish to create your own msbuild based solution.
UPDATE 2009-05-21
I've been testing the #2 method of using a single network share. It is resulting in some issues with Windows Server 2003 under load:
http://support.microsoft.com/kb/810886
end update
I've received a proposal for an ASP.NET website that works as follows:
Hardware load-balancer -> 4 IIS6 web servers -> SQL Server DB with failover cluster
Here's the problem...
We are choosing where to store the web files (aspx, html, css, images). Two options have been proposed:
1) Create identical copies of the web files on each of the 4 IIS servers.
2) Put a single copy of the web files on a network share accessible by the 4 web servers. The webroots on the 4 IIS servers will be mapped to the single network share.
Which is the better solution?
Option 2 obviously is simpler for deployments since it requires copying files to only a single location. However, I wonder if there will be scalability issues since four web servers are all accessing a single set of files. Will IIS cache these files locally? Would it hit the network share on every client request?
Also, will access to a network share always be slower than getting a file on a local hard drive?
Does the load on the network share become substantially worse if more IIS servers are added?
To give perspective, this is for a web site that currently receives ~20 million hits per month. At recent peak, it was receiving about 200 hits per second.
Please let me know if you have particular experience with such a setup. Thanks for the input.
UPDATE 2009-03-05
To clarify my situation - the "deployments" in this system are far more frequent than a typical web application. The web site is the front end for a back office CMS. Each time content is published in the CMS, new pages (aspx, html, etc) are automatically pushed to the live site. The deployments are basically "on demand". Theoretically, this push could happen several times within a minute or more. So I'm not sure it would be practical to deploy one web server at time. Thoughts?
I'd share the load between the 4 servers. It's not that many.
You don't want that single point of contention either when deploying nor that single point of failure in production.
When deploying, you can do them 1 at a time. Your deployment tools should automate this by notifying the load balancer that the server shouldn't be used, deploying the code, any pre-compilation work needed, and finally notifying the load balancer that the server is ready.
We used this strategy in a 200+ web server farm and it worked nicely for deploying without service interruption.
If your main concern is performance, which I assume it is since you're spending all this money on hardware, then it doesn't really make sense to share a network filesystem just for convenience sake. Even if the network drives are extremely high performing, they won't perform as well as native drives.
Deploying your web assets are automated anyway (right?) so doing it in multiples isn't really much of an inconvenience.
If it is more complicated than you're letting on, then maybe something like DeltaCopy would be useful to keep those disks in sync.
One reason the central share is bad is because it makes the NIC on the share server the bottleneck for the whole farm and creates a single point of failure.
With IIS6 and 7, the scenario of using a network single share across N attached web/app server machines is explicitly supported. MS did a ton of perf testing to make sure this scenario works well. Yes, caching is used. With a dual-NIC server, one for the public internet and one for the private network, you'll get really good performance. The deployment is bulletproof.
It's worth taking the time to benchmark it.
You can also evaluate a ASP.NET Virtual Path Provider, which would allow you to deploy a single ZIP file for the entire app. Or, with a CMS, you could serve content right out of a content database, rather than a filesystem. This presents some really nice options for versioning.
VPP For ZIP via #ZipLib.
VPP for ZIP via DotNetZip.
In an ideal high-availability situation, there should be no single point of failure.
That means a single box with the web pages on it is a no-no. Having done HA work for a major Telco, I would initially propose the following:
Each of the four servers has it's own copy of the data.
At a quiet time, bring two of the servers off-line (i.e., modify the HA balancer to remove them).
Update the two off-line servers.
Modify the HA balancer to start using the two new servers and not the two old servers.
Test that to ensure correctness.
Update the two other servers then bring them online.
That's how you can do it without extra hardware. In the anal-retentive world of the Telco I worked for, here's what we would have done:
We would have had eight servers (at the time, we had more money than you could poke a stick at). When the time came for transition, the four offline servers would be set up with the new data.
Then the HA balancer would be modified to use the four new servers and stop using the old servers. This made switchover (and, more importantly, switchback if we stuffed up) a very fast and painless process.
Only when the new servers had been running for a while would we consider the next switchover. Up until that point, the four old servers were kept off-line but ready, just in case.
To get the same effect with less financial outlay, you could have extra disks rather than whole extra servers. Recovery wouldn't be quite as quick since you'd have to power down a server to put the old disk back in, but it would still be faster than a restore operation.
Use a deployment tool, with a process that deploys one at a time and the rest of the system keeps working (as Mufaka said). This is a tried process that will work with both content files and any compiled piece of the application (which deploy causes a recycle of the asp.net process).
Regarding the rate of updates this is something you can control. Have the updates go through a queue, and have a single deployment process that controls when to deploy each item. Notice this doesn't mean you process each update separately, as you can grab the current updates in the queue and deploy them together. Further updates will arrive to the queue, and will be picked up once the current set of updates is over.
Update: About the questions in the comment. This is a custom solution based on my experience with heavy/long processes which needs their rate of updates controlled. I haven't had the need to use this approach for deployment scenarios, as for such dynamic content I usually go with a combination of DB and cache at different levels.
The queue doesn't need to hold the full information, it just need to have the appropriate info (ids/paths) that will let your process pass the info to start the publishing process with an external tool. As it is custom code, you can have it join the information to be published, so you don't have to deal with that in the publishing process/tool.
The DB changes would be done during the publishing process, again you just need to know where the info for the required changes is and let the publishing process/tool handle it. Regarding what to use for the queue, the main ones I have used is msmq and a custom implementation with info in sql server. The queue is just there to control the rate of the updates, so you don't need anything specially targeted at deployments.
Update 2: make sure your DB changes are backwards compatible. This is really important, when you are pushing changes live to different servers.
I was in charge of development for a game website that had 60 million hits a month. The way we did it was option #1. User did have the ability to upload images and such and those were put on a NAS that was shared between the servers. It worked out pretty well. I'm assuming that you are also doing page caching and so on, on the application side of the house. I would also deploy on demand, the new pages to all servers simultaneously.
What you gain on NLB with the 4IIS you loose it with the BottleNeck with the app server.
For scalability I'll recommend the applications on the front end web servers.
Here in my company we are implementing that solution. The .NET app in the front ends and an APP server for Sharepoint + a SQL 2008 Cluster.
Hope it helps!
regards!
We have a similar situation to you and our solution is to use a publisher/subscriber model. Our CMS app stores the actual files in a database and notifies a publishing service when a file has been created or updated. This publisher then notifies all the subscribing web applications and they then go and get the file from the database and place it on their file systems.
We have the subscribers set in a config file on the publisher but you could go the whole hog and have the web app do the subscription itself on app startup to make it even easier to manage.
You could use a UNC for the storage, we chose a DB for convenience and portability between or production and test environments (we simply copy the DB back and we have all the live site files as well as the data).
A very simple method of deploying to multiple servers (once the nodes are set up correctly) is to use robocopy.
Preferably you'd have a small staging server for testing and then you'd 'robocopy' to all deployment servers (instead of using a network share).
robocopy is included in the MS ResourceKit - use it with the /MIR switch.
To give you some food for thought you could look at something like Microsoft's Live Mesh
. I'm not saying it's the answer for you but the storage model it uses may be.
With the Mesh you download a small Windows Service onto each Windows machine you want in your Mesh and then nominate folders on your system that are part of the mesh. When you copy a file into a Live Mesh folder - which is the exact same operation as copying to any other foler on your system - the service takes care of syncing that file to all your other participating devices.
As an example I keep all my code source files in a Mesh folder and have them synced between work and home. I don't have to do anything at all to keep them in sync the action of saving a file in VS.Net, notepad or any other app initiates the update.
If you have a web site with frequently changing files that need to go to multiple servers, and presumably mutliple authors for those changes, then you could put the Mesh service on each web server and as authors added, changed or removed files the updates would be pushed automatically. As far as the authors go they would just be saving their files to a normal old folder on their computer.
Assuming your IIS servers are running Windows Server 2003 R2 or better, definitely look into DFS Replication. Each server has it's own copy of the files which eliminates a shared network bottleneck like many others have warned against. Deployment is as simple as copying your changes to any one of the servers in the replication group (assuming a full mesh topology). Replication takes care of the rest automatically including using remote differential compression to only send the deltas of files that have changed.
We're pretty happy using 4 web servers each with a local copy of the pages and a SQL Server with a fail over cluster.