How to develop a web application that is load-balance friendly - c#

Starting to develop to actual code to my website and wanted to know how do i develop or design the website that is load balance friendly. I read a post on stackoverflow regarding scalability and the selected answer stated: "Make sure you consider load balancing when developing your application". How do I go about this?

Your decision will come down to environment. If this is a product for sale, you will not have any control over the load balancing implementation. This means that "sticky sessions," where a user is bound to the same server for the duration of a session, cannot be guaranteed. Sticky sessions allow just about any application to be load-balanced, but they are not as efficient.
If you cannot guarantee an implementation with sticky sessions, avoid the usage of Session state altogether, or look into a shared-session solution.

1) do not use static fields to store data, statistics, ...
2) use session with care - you can still use in-process with sticky ssessions but I do not like it.
3) Do not rely on the IP of the server

Well, one answer is to reduce reliance upon session variables. It's possible to share session variables between servers via session server, but that means all your servers have a single point of failure on the session server then, plus reducing performance.
Basically, just try to make each page as stand-alone and stateless as possible, and you'll be good.

This might be obvious to most of you, but actually was an issue in our environment when we started to use a load balancer / several web servers: Do not rely on the IP addresses of your web server.
We had a production environment that used a switch and a set of internal IP addresses, including the one of the web server (our products usually run in a closed off environment, not the open Internet). If you have several web servers that becomes a problem.

Make sure you have a development/QA environment where you can test your software in a load balanced environment and see the issues in your code as you develop it rather than waiting until the deployment day.

One thing to take into account is the usage of Session data to maintain state.
As your application subsequent requests can be handled by other servers in the balance line you can not use InProc mode and StateServer mode.

Related

ASP.NET Cache Management

I have three applications running in three separate app pools. One of the applications is an administrative app that few people have privileged access to. One of the function the administrative app allows is creating downtime notices. So when a user goes into the administrative app and creates a downtime notice the other two apps are supposed to pick up on there being a new notice and display it on the login page.
The problem is that these notices are cached and being that each app is in a separate app pool the administrative app doesn't have any way to clear the downtime notices cache in the other two applications.
I'm trying to figure out a way around this. The only thing I can think of is to insert a record in the DB that denotes the cache needs to be cleared and the other two apps will check the DB when loading the login page. Does anyone have another approach that might work a little cleaner?
*Side note, this is more widespread than just the downtime notices, but I just used this as an example.
EDIT
Restarting the app pools is not feasible as it will most likely kill background threads.
If I understand correctly, you're basically trying to send a message from the administrative app to other apps. Maybe you should consider creating WCF service on these apps that could be called from the administrative application. That is a standard way to communicate between different apps if you don't want to use e.g. shared medium such a database and it doesn't force you to use polling model.
Another way to look at this is that this is basically an inter-application messaging problem, which has a number of libraries already out there that could help you solve it. RabbitMQ comes to mind for this. It has a C# client all ready to go. MSMQ is another potential technology, and one that already comes with Windows - you just need to install it.
If it's database information you're caching, you might try your luck at setting up and SqlCacheDependency.
Otherwise, I would recommend not using the ASP.NET cache, and either find a 3rd party solution that uses a distributed caching scheme, that way all applications are using one cache, instead of 3 separate ones.
I'm not saying this is the best answer or even the right answer, its just what I did.
I have a series of ecommerce websites on separate servers and data centers that rely on pulling catalog data from a central backoffice website location and then caches them locally. In my first iteration of this I simply used GET requests that the central location could ping the corresponding consuming website to initiate its own cache refresh routine. I used SSL on each of the eCommerce servers as I already had that setup and could then have the backoffice web app send credentials via SSL GET to initiate the refresh securely.
At a later stage, we found it more efficient to use sockets instead on the backoffice where each consuming website would be a client and listen for changes in the data. The backoffice website could then communicate to its corresponding website when a particular account change and then communicate this very specifically. This approach is much more granular and we could update in small bits as needed as opposed to a large chunked update but this was definitely more complicated than our first try.

Running e-commerce site from a web service. Bad idea?

The company I work for makes a complex accounting application. This is a desktop app that connects to a local database server on the client's network. Some of our clients want to get e-commerce sites built but they will need access to this data.
Is it OK to install the web site at one location and feed data to it from a web server in another location. I've built stuff like this in the past and I know it could potential be slow. I'm hoping to mitigate this problem with stacks of Asp.NET caching. Is this a reasonable architecture (for a small to medium size e-commerce site) or will it run like a dog? Due to much pain in the past, I'm trying to keep this simple and avoid any sort of replication of the database.
Cheers
Ma
Well, replication of the database might actually be the fastest option. Think about it: getting a whole bunch of data on each request, with some cache misses, or basically having a 'complete' local cache (and thus no cache misses, well, not in-transfer anyway, your DB might cache, of course).
Edit: so basically my answer would be: no, it's not OK to run the website and database in two completely different locations. Two boxes in the same rack could be OK, but it seems that it would be preferable to have your web-service and DB on the same (virtual) machine.

Session State Server vs Custom Session State Provider

I have been tasked to scale out the session for an application. From my research the most obvious choice is to use the State Server session provider, because I don't need the users sessions to persist (SQL Server Session provider)
About the app:
Currently using InProc session provider
All objects stored in session are serializable
All objects are small (mostly simple objects (int, string) and a few simple class instances)
Before I dive head-first into the IT side of things and with the ability to provide a custom session provider with ASP.NET 4, should I even consider a custom session state provider. Why or why not? Are there any "good" ones out there?
Thanks!
User feedback:
Why are we using session: persistence of data between postbacks (e.g. user selections)
How: user makes a selection, selection is stored. User leaves a page and returns,
selections are restored. etc. etc.
Will be creating a web farm
I've provided some links you can read up on on properly scaling session using the state server.
Useful links from Maarten Balliauw's blog:
http://blog.maartenballiauw.be/post/2007/11/ASPNET-load-balancing-and-ASPNET-state-server-%28aspnet_state%29.aspx
http://blog.maartenballiauw.be/post/2008/01/ASPNET-Session-State-Partitioning.aspx
http://blog.maartenballiauw.be/post/2008/01/ASPNET-Session-State-Partitioning-using-State-Server-Load-Balancing.aspx
My State Server related projects:
http://www.codeproject.com/KB/aspnet/p2pstateserver.aspx (latest code at https://github.com/tenor/p2pStateServer)
http://www.codeproject.com/KB/aspnet/stateserverfailover.aspx
Hope that helps.
It depends on what you mean by "scaling" session storage. If your simply talking about session state performance, your not going to beat the in-process session state provider. Switching to the State Server provider will actually make things slower -- due to the extra overhead of serializing and transferring objects across process boundaries.
Where the State Server can help you scale, is that it allows multiple machines in a load balanced web-farm to share a single session state. It is limited by machine memory, however, and if you will have lots of concurrent sessions you may want to use the SQL Session State provider.
For the most performance in a web farm, you can also try using AppFabric as was previously suggested. I haven't done it myself but it is explained here.
Also, here's a link for using Memcached as a Session State provider. Again, I haven't used it, so I can't offer an opinion on it...
EDIT: As #HOCA mentions in the comments, there are 3rd party solutions if cost isn't an issue. One I've heard of (but not used) is ScaleOut SessionServer.
I would highly recommend that before you look in to scaling out session that you first evaluate whether session was even needed in the first place.
Session variables are serialized and deserialized for every single page load whether the page uses that data or not. (EDIT: Craig pointed out that you have some level of control over this in .net 4 http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstatebehavior.aspx However, this still has drawbacks, see comments to this answer.)
For single server instances this is okay as you are just pulling it from the local memory of your web server. The load on these apps tend to be pretty small so caching user specific information locally makes sense.
However, as soon as you move storage of session to another server you have increased the network requirements and page load times of your application. Namely, every page will result in the session data to be moved from the remote server, across the network wire, and into memory of the web server.
At this point you have to ask yourself: is the load to pull this information from the database server directly as necessary more than pulling it from the session server every single time?
There are few instances where pulling it from the database server as needed takes longer or results in more traffic than grabbing it from a remote session server.
Bearing in mind that a lot of people set up their database server(s) to also be session servers and you start to see why use of session doesn't make any sense.
The only time I would consider using session for load balanced web apps is if the time to acquire the data exceeded a "reasonable" amount of time. For example, if you have a really complex query to return a single value and this query would have to be run for lots of pages. But even then there are better ways that reduce the complexity of dealing with remote session data.
I would advise against the use of session state, regardless of the provider.
Especially with your "very small objects" use viewstate. Why?
Scales best of all. NOTHING to remember on the server.
NO worries about session timeout.
No worries about webfarms.
No worries about wasted resources for sessions that will never come back.
Especially in ASP.NET 4 viewstate can be very manageable and small.

Can I host an ASP.NET webite outside of IIS?

I need to write an ASP.NET application which must handle a very large number of transactions per second - as many as 5000 users may transact at the same time. I think I will use WCF in back to communicate with SQL server. But in front, can IIS handle 5000 users at the same time effectively, or is there any simple way to host my application outside of IIS?
It will depend on the characteristics of the machine but you could always setup a web farm to handle high loads.
You can host a WCF application outside of IIS using WAS, Windows Service or a .NET application.
It certainly would be possible to design a system using IIS that could handle the load you describe. Whether this is a good idea or not really depends on the application. I suggest perhaps you look at some benchmarking some of the loads to determine if it is quicker to host in IIS or if you host a WCF application outside of IIS.
Why you need it outside IIS. you can have 5000 TPS with IIS. But bear in mind that it depends from lot of aspects... like hardware, what configuration you have for your servers, it depends from heaviness of your application, what is the response time of your applications. Also as suggested you can have web farm. You can use load balancer and have several servers behind it. So it is possible just you need to have a proper design and if needed a budget for hardware upgrade.

Why is it a bad idea to use Session to store state in high traffic websites?

I am watching the ASP.NET learn videos on asp.net/learn. In this tutorial, they are building a quiz engine. At one point, the narrator explains that we are going to use the Session object to maintain the state between each page (each page contains a question and four answers). He says that "since this is a low traffic website" it is okay to use Session and that he doesn't have the time to implement a more sophisticated method.
I am just wondering what alternate method(s) is he hinting at? And why is session a bad choice for a high traffic website?
Storing data in a database, or in cookies or some other method that is not directly tying up web server memory.
In addition to load, session also raises issues with the ability to use farms since you would either need to synchronize the session across the farm, or make sessions sticky, which can impact scalability.
For alternatives you can read the article Nine Options for Managing Persistent User State in Your ASP.NET Application.
In the articles the author explains the pros and cons of each method.
From the summary:
ASP.NET provides many different ways
to persist data between user requests.
You can use the Application object,
cookies, hidden fields, the Session or
Cache objects, and lots of other
methods. Deciding when to use each of
these can sometimes be difficult. This
article will introduce the
aforementioned techniques and present
some guidelines on when to use them.
Although many of these techniques
existed in classic ASP, best practices
for when to use them have changed with
the introduction of the .NET
Framework. To persist data in ASP.NET,
you'll have to adjust what you learned
previously about handling state in
ASP.
Session data is stored in the RAM of the server, if you have a high traffic site that is going to get full real quick and the last thing you want is that data being swapped to disk.
As gaijin42 says, cookies or a DB are the alternative.
Session as a state storage method is rough in high traffic systems for several reasons.
First, the default Session storage method is in-process, meaning that if you have a load-balanced web farm, you'll constantly 'lose' Session information as a user gets pages served from different servers.
The in-proc Session server also dies when an app pool is recycled, which happens more often on higher traffic servers.
The scalability options for Session data are
Use the freely available ASP.NET
Session Server and point all your
applications at it
Use SQL Server to store Session data.
Due to the nature of Session data in general, neither of these is a very good option for a very high traffic site (unless you have unlimited money to throw at the hardware).
For high traffic websites you might be looking at Memcached. It is a caching mecanism that is stored on the RAM of a remote computer. Just recently a win32 port has been made of the library (was only possible with linux before).
I'm not going to repeat what was already mentioned here, but another alternative is using the Application hash. It should be used sparingly, since it will consume memory on your web server as Adam has already mentioned, but it does provide a good way to cache things that are common across ALL your users.
This keeps you from having to go back to your database to retrieve information that most likely was already asked for by someone else.
Another alternative similar to Application is Cache which has more flexibility in terms of when it gets released, duration, etc.
Here's some links in case you're interested:
ASP NET Caching Application State
We use a database for anything high traffic or that will result in large session state. Instead we store a pointer in the real sessionstate that points to our database record. Then the only overhead we have is the bandwidth between the web server and database server which will be much less than between any given user and the web server.

Categories

Resources