Scaling an Entity Framework Application / Multiple Apps hitting the same database? - asp.net-mvc

I have a application that has been programmed with MVC/EF Code First. It does a lot of server side processing and is pretty resource intensive.
I know how to set up load balancing, but, I want to know if scaling an EF application is as simple as provisioning a new server, deploying the application and pointing to the DB cluster - or are there any issues I will face with regards to multiple EF applications hitting the same database server?
I can't seem to find any advice/guides for this and I am worrying I made the wrong choice by choosing EF over something simpler/more straight forward!

... issues ... regards to multiple EF applications hitting the same database server?
Rewind a bit to the fact that your application is an ASP .NET MVC based application. Having multiple instances of it is probably going to raise the spectre of state management.
MSDN has a pretty good introduction to why this is an issue:
HTTP is a stateless protocol. This means that a Web server treats each HTTP request for a page as an independent request. The server retains no knowledge of variable values that were used during previous requests. ASP.NET session state identifies requests from the same browser during a limited time window as a session, and provides a way to persist variable values for the duration of that session. By default, ASP.NET session state is enabled for all ASP.NET applications.
Alternatives to session state include the following:
Application state, which stores variables that can be accessed by all users of an ASP.NET application.
This point is an extremely common way of storing state, but breaks down when there's multiple instances of an application involved (the state is "visible" to only one of the instances).
Typically this is worked around by using either the StateServer or SQLServer value of SessionStateMode. The same article provides a pretty good summary of each option (emphasis mine).
StateServer mode, which stores session state in a separate process called the ASP.NET state service. This ensures that session state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm.
SQLServer mode stores session state in a SQL Server database. This ensures that session state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm.
If your application is stateless, this is a moot point.
I am worrying I made the wrong choice by choosing EF
As far as issues with multiple instances of your application accessing a database go, you're going to have issues with any sort of data access technology.
Here's the basic scenario: let's say your application sends welcome emails to users on a schedule.
Given the table Users:
UserId | Email | WelcomeLetterSent
-------+-----------------+------------------
1 | user#domain.com | 0
And some psuedo-code:
foreach (var user in _context.Users.Where(u => !u.WelcomeLetterSent))
{
SendEmailForUser(user);
user.WelcomeLetterSent = true;
}
_context.SaveChanges();
There's a race condition where both instance one and instance two of your application might simultaneously evaluate _context.Users.Where(...) before either of them has the chance to set WelcomeLetterSent = true and call SaveChanges. In this case, two welcome emails might get sent to each user instead of one.
Concurrency can be an insidious thing. There's a primer on managing concurrency with the Entity Framework over here, but this is only the tip of the iceberg.
The answer to your question? It depends on what your application does :)
On top of that, I ideally want to build some "extra" support applications that hook in to the same DB... and, I am just not sure how EF will handle multiple apps to the same DB....
If your application can tolerate multiple instances of itself accessing one database, then it's usually not a stretch to make these "support applications" play nicely. It's not much different whether the concurrency is from multiple instances of one application or multiple applications with one instance each.

Related

Is there any way to work with sessions without locking on ASP.Net MVC site?

Is there any way to work with sessions without locking on ASP.Net MVC site ?
Session lock mechanism leads many problems;
When your site slow down little bit, users are start to hit "F5" on the keyboard. When they do this, requests are starting to wait each other. All those requests are hanging on IIS at "RequestAcquireState" state for session module.
If a user made a simultaneous requests this will happen. Because session module in IIS and default session provider (Or generally custom ones) has both lock mechanism.
See:
Implementing a Session-State Store Provider
Session State Providers
There is locking, because your workflow can be manipulated if you are not carefully designed your process. Been hacked is way big problem for you comparing with performance issues...
But if you designed your process for shared, semi-consistent state store, (Or simply maybe there is no need to use) can we remove locking situation from our way completely?
Yes we can remove lock from our way with "UnlockedStateProvider".
It designed for MVC and not implements .Net SessionStateStoreProviderBase because, IIS session module also has locking mechanism.
It is a simple ActionFilterAttribute provide state store for you via HttpContext.
It has also Redis provider so you can use safely in web farm, Azure or AWS.
Please take a look:
https://www.nuget.org/packages/UnlockedStateProvider.Redis
https://github.com/efaruk/playground/tree/master/UnlockedStateProvider
Note: Developed for advanced usage and not a replacement for any SessionStateProvider...

Deploying an ASP.NET MVC in production, while users are still online

I need to know the best practices for deploying a new version of an ASP.NET MVC application while users are still connected to it
Everytime one deploys the .dll that contains the models and controllers of the application, the application is rebooted. Also deploying the web.config (that references eventually new libraries) results in rebooting the application.
So, the question is: how do I update the application's dll or web.config without disconnecting the users from the site?
You want to use another session state option other than using in-proc so your users survive when the process recycles or system reboots.
InProc: In-Proc mode stores values in the memory of the ASP.NET worker process. Thus, this mode offers the fastest access to these values. However, when the ASP.NET worker process recycles, the state data is lost.
See ASP.NET Session State Options for more ASP.NET options and mentions of other third party session state providers.
This question also deals with possible deployment scenarios to help with the websites under load and slow app times after a pool recycle: How are people solving app pool recycle issues on deployment with large apps?
Ideally you want to be as stateless as you can, and stay away from session. Perhaps you can use a cookie for tracking the current user via forms auth for example. But you must stay away from in-proc by using distributed cache/session provider so users won't lose session state on app pool recycles.
I think the best is to deploy a new site for new sessions, and mantain existing sessions in the old one.
I feel that "The blue green deployment strategy" article linked below can be hacked with a few changes to do that (Disallow New Connections instead of issue a "drain", using sticky sessions).
https://kevinareed.com/2015/11/07/how-to-deploy-anything-in-iis-with-zero-downtime-on-a-single-server/

Maintaining state in Asp.Net MVC website

I'm currently designing a new website built on MVC and I wonder what is the right way to manage state.
The state should contain the userId and some structs of the user info, and should be kept during the whole session of the user while he's logged in (across http requests)
The important criteria:
1) Support scalability
2) Performance
The easy way is to use the Session object, but it doesn't support scalability. If different requests during the session go through different IIS servers, the session won't be kept. Although I've heard of load balancing tools which route all requests of a single session through the same machine, I'm not sure that it's a good practice to rely on it (isn't it?)
Another option that I've read about, is keeping the state data in special state servers which are running a RAM DB (like Cassandra for Linux or Redis for Windows). But it seems to me an overkill at this stage of the development.
Do you have any other suggestions?
I would like to start with something simple at the moment, but keep the design ready for a more advanced solution at the future.
Any best practice or code/design suggestions will be appreciated.
Thanks,
Edi.
(1) Use Sql Server to Store Session State
(2) Use Memcached as a Session State Provider
(3) Cook up your own solution using Caching on an external caching provider: look into using something like the ServiceStack Caching Framework. Using this, you can use Redis, Memcached, Azure or AWS to handle caching.
Next, create a KeyFactory to handle generation of keys for specific items. The item keys would include the UserId (which you would always have from FormsAuthentication UserId (assuming that you are using FormsAuthentication). Then store any Session data for the user in the cache. Using this approach you are using Caching in place of Session, and the cache can be shared across multiple servers.
Note: you can have different approaches regarding clearing out the user's data whenever they begin a new session. Potential approaches include:
Include the user's session start dateTime in the cacheKey, and auto-expire entries when they are no longer fresh
Clear out all potential entries for a user when they begin a new session
If you are using .NET 4.5 and dependent on the type and amount of information you are keeping on users you may want to look at using claims to store information about the user. In .NET 4.5 all Principals inherit from ClaimsPrincipal. ClaimsPrincipal already uses claims to store the user name, roles and other information. You can create your own service to transform claims, which will allow you to add additional information to the Principal user.

nHibernate strategies in a web farm

Our current project at work is a new MVC web site that will use a WCF service primarily to access a 3rd party billing system via a web service as well as a small SQL database for user personalization. The WCF service uses nHibernate for the SQL database.
We'd like to implement some sort of web farm for load balancing as well as failover and maintenance. I'm trying to decide the best way to handle nHibernate's caching and database concurrency if there are multiple WCF services running.
Some scenarios I've been thinking about...
1) Multiple IIS servers, one WCF server. With this setup, the WCF server would be a single point of failure, but there would be no issues with nHibernate caching or database concurrency.
2) Multiple IIS servers, each with it's own WCF service. This removes a single point of failure, but now nHibernate on one machine would not know about database changes done by another machine.
Some solutions to number 2 would be to use an IStatelessSession so we're not doing any caching and nHibernate is always fetching directly from the database. This might be the most feasible as our personalization database has very few objects in it. I'm also considering a 2nd-level cache such as memcached or Velocity, but it may be overkill for this system.
I'm putting this out there to see if anyone has experience doing this sort of architecture and to get some ideas for a solution. Thanks!
am i missing something here, i don't see a problem with nhibernate on the webservers.
application cache would not be a problem as each nhibernate box would keep it's own cache which would be populate from the datastore. look at creating a table that can be monitored for reasons to do a cache refresh. we used to do this using using CacheDependency class in .net 2.0 that would detect changes to a column and then remove the relevant item from the cache. so if a user inserts a new product, the cache would be dropped and the next call to get the products would load the cache again. it's old but check out: http://msdn.microsoft.com/en-us/magazine/cc163955.aspx#S2 for the concept. cheers
I would suggest not doing caching until not doing caching becomes a problem. Your DB will do its own caching to save you searching for the same data repeatedly, so the only thing you have to worry about is data across the wire. Judging by your description, you're not going to have a problem there. If you ever get to a stage where you do, use a distributed cache - allowing your servers to cache separately will cause you bouncing data problems on refresh.

ASP.net MVC: Where to keep application data?

I am just starting porting an application to ASP.net MVC and I have an object holding application state (it keeps track of certain processes running on the machine, starting and stopping as necessary and sending/receiving MSMQ message).
Where should I keep this object? In my current application (based on HttpListener) it is a singleton, however I know singletons make testing difficult. It would be difficult to mock or test this object, at least in the context of the MVC application itself, and it has it's own set of tests outside the application anyway. However it may need to be replaced by a stub for testing.
The object needs to be made available to a number of controllers. Where should I store this object and how should I make it available to the controllers? I've never seen a case like this described in any ASP.net MVC examples I've seen.
UPDATE:
I guess I need to explain why I can't store this data in a database. First I must explain what the application does:
The application serves images that are generated dynamically by a number of "engines", which are processes running on the server, communicated to via MSMQ. Lets call the object I'm asking the question about the EngineManager. The process goes something like this:
The client POSTs an XML request to the server, giving the name of "engine" to be used, as well as a number of parameters describing the image.
The application checks the EngineManager to see if that engine is running. If not, it starts it.
The application posts an MSMQ message to the engine and waits for the response.
The application sends the generated image back to the client.
If at any point the engine shuts down or crashes, the application must be aware of that so that it can be restarted on the next request to that engine.
When the application shuts down, all engines are also shut down.
There are several controllers that handle these requests, each doing a slightly different job. All of them need to communicate with the same EngineManager, as it also needs to, in certain situations synchronise access to other resources.
As you can see, it's not your typical database-backed webserver.
You should pass the object to the constructor of each Controller instance, and the controller action methods should all use the object instance passed in to the Controller instance constructor.
The default ControllerFactory which ships with ASP.NET MVC will not allow you to do this. However, there are free addon frameworks (the one I like is Autofac) which do permit this style of programming.
If you want this object to be available to all users, i.e. it is not session specific, you could look at storing it in application state:
http://msdn.microsoft.com/en-us/library/bf9xhdz4(VS.71).aspx
However, application state has several disadvantages, as listed on the page linked above, so make sure these issues don't affect you before you go down that route. In general I steer clear from Applciation state and store application data in a backend DB. As you don't want to go down this route application state may be OK for you.

Resources