Azure Virtual Machines not holding Logged in User Session - asp.net-mvc-4

I am developing a MVC4 application . We have hosted our application on Windows Azure IAAS Model . Right now we have configured 2 virtual machines and everything is working good. But we have an issue with maintaining User Loging .
If i login in virtual machine 1 , its not getting carried over ,when the next request is coming from Virtual machine 2 . We have mapped two virtual machines over load balance .
Should i look into Cache solutions . Any input will be greatly helpful ...
Thanks,
Jaswanth

You're hitting two completely separate VMs (yes load balanced, but separate). This mandates the need for storing any type of session data external to the VMs (or you need to sync the session content and have it identical in both VMs).
Azure doesn't do anything to sync session data for you. That's on you, to build it into your app's architecture. You mentioned caching, which is certainly a viable solution (which you pick, though, is up to you). There are other solutions too such as database-based session storage. Again, that's up to you.
But bottom line: If you're going to scale an app beyond a single server (VM in this case), in a load-balanced way, you cannot store session data in a specific vm.

Use a durable session state store (like Redis or SQL Server, etc) or put your state in a cookie and read/write it on each request. If cookie includes sensitive content, encrypt it.

Related

Verify Load balancing Azure Container Service

I am using the Azure Container Service with Kubernetes orchestrator and have an app deployed on a cluster with 3 nodes. It has 5 replicas. How can I verify load balancing in action e.g. I want to be able to see that every time I hit the external IP I am being routed to perhaps a different node. Thanks.
The simplest solution is to connect (over ssh for example) to 3 nodes and run WinDump there. In order everything is working properly you will be able to see what happens on every node.
Also here is Microsoft documentation for testing a load balancer:
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/tutorial-load-balancer#test-load-balancer
The default Load Balancer which are available to your Windows Azure Web and Worker roles are software load balancers and not so much configurable however they do work in Round Robin setting. If you want to test this behavior this is what you need to do:
Create two (or more) instances of your service with RDP access
enabled so you can RDP to both instances
RDP to your both instances and run NETMON or any network monitor
solution in it.
Now access your Windows Azure web application from your desktop You
need to understand that when a network connection is made from your
desktop the connection is still alive based on network settings
(default 60 seconds) so you need to wait until default timeout is
passed to access your Windows Azure web application again.
When you will access your Windows Azure Web application again you can
verify that seconds time the request went to next instance. BE sure
to pass the connection timeout otherwise your request will be keep
handled by same instance.
Note: If you dont want to use RDP, you sure can also create a test ASP.NET page to write some special code based on your specific instance which will show you that this page is specific to certain instance. The best way to do is to read the Instance ID as below:
int instanceID = RoleEnvironment.CurrentRoleInstance.Id;
If you want to have more control over Windows Azure Load Balancing, i would suggest using the Windows Azure Traffic Manager which will help you to route the traffic to your site via Round-Robin, Performance or backup based scenario. More info on using Traffis Manager is in this article.

Azure Web App and sticky session with Affinity Cookie – Reliable?

I did a production release for one of my clients with Azure PAAS – Azure Web App (formerly Azure Websites). We marked the site in Auto scale mode with 2 minimum instances. We started getting complains from the users that intermittently users are experiencing some issues which can cause only if they lose the session variables while actively using the site.
We were wondering how that can happen since we are maintaining the sessions in "in proc". We didn’t go for a separate out of proc session manager (Redis cache / DB based) on the day 1 because, according to the documentation, Azure Web app runs with a sticky session load balancer (when running with multiple instances) by default. It injects ARR affinity cookie in the Http response that helps in redirecting a user to the same instance with which it established the session at the first time.
To debug this issue, we started printing the actual sessionId in the page. After many attempts, we reproduced the issue – surprisingly sessions are getting swapped. Lets say – my session Id is “1eocgtmwwwwvs1cxksyofne4”, after the page refreshes it got changed to “5p1hsxszq2mcqmt5i5ytqg12” including all other information that are managed in session variable. Scary… isn’t it?
Reached out to support with an Emergency ticket – the response is:
"Azure Web Apps is a stateless platform and our recommendations is to implement a Session Management solution that best works for your environment and avoid the dependency on In-memory session state management especially in cases where your Web App is hosted on multiple servers . In your case as you are considering to implement a Caching solution for session management in near future , our recommendation is to move to a single instance as a workaround for now . We will assist you in ensuring that the app is working as expected on a single instance.”
I completely understand that – but why Affinity cookie will fail. I know that Affinity cookie can be disabled and I didn’t disable it. I thought of sharing this story. It could be useful for any other person relying on Affinity cookie based sticky load balancer.
BTW: Redis session provider implementation is very easy. It took just a few mins to implement.
Doing a postmortem now – what went wrong? I didn’t consider the cookie ‘not supported’ browsers. Then why would it fail intermittently even in my browser where I support cookie. PAAS resources are constantly in move / getting swapped .. .. and there is no way we can use in proc session … etc

Can Cloudbees instances within an app communicate directly?

I am looking to build an Akka-based application in the cloud, for a garage startup that I'm bootstrapping; by the nature of the app, it's semi-stateful, with as much as possible cached in RAM for performance. (It'll be tolerant of being shut down and restarted periodically, but we want to mostly operate via cached information inside the Actors.)
The architecture is designed for a cluster of servers, communicating between them as necessary so that a user session on node A can query a middleware Actor on node B when appropriate. So my question is, how hard is that in CloudBees?
My understand from this page is that there is no automatic directory service to manage this sort of intra-cluster communication yet, but I can probably live with that -- worse comes to worst, I should be able to manage discovery via the DB, with each node registering itself when it comes up and opening up many-to-many communications with the others.
What I want to check, though, is that this communication is straightforward. Does each node have a reliable local IP that it can advertise for others to contact it on, that is at least stable during this run of the application? Or is there another/better way for a node to advertise its address to the rest of the nodes running this app?
(I assume that the nodes of an app all share the same DB instance.)
Any guidance here would be greatly appreciated. I'd like to choose a hosting provider soon, and keep returning to CloudBees as the most promising-looking of the options...
There are no limitations currently on instances communicating with each other - the trick is in discovering membership. There is an api that will be shortly be released that will allow you to track membership - but for now, the following may work:
To get the port, look at the file names in $PWD/.genapp/ports (as applications can have multiple ports) - (eg System.getenv("PWD") + ".genapp/ports" - list the files in that directory - generally will be just 1 - the file name is the port). There are other ways - for example the "sun.java.command" system property on JVM apps too.
The hostname can be obtained via the usual means (eg InetAddress.getLocalHost().getHostName()): this host
name will be the private name - ie it will resolve to a private IP -
good for node to node communication.
Public IP/hostname: perform a HTTP get (from the server) to the following URL:
http://instance-data/latest/meta-data/public-hostname (will only
return the public IP on the server side of course).
(see http://developer-blog.cloudbees.com/2012/11/finding-port-or-address-of-your.html)
You can then, as you say, on startup, register the appropriate port/private hostname with a DB, and then read that on each node to "seed" the cluster (akka doesn't have to know about all members - just enough seeds) I would think a 2 phase startup: 1: register host/port, 2, look for other members, add them as seed members to the local Akka configuration (may need to periodically do the same for a while, as other nodes startup - to ensure it is seeded enough)
From my reading of Akka setup here: http://doc.akka.io/docs/akka/snapshot/scala/remoting.html
It looks like you can specify the port - so if possible, I would set that to be the app_port environment variable - that means each node can communicate via the private hostname with that port. However, http traffic will also be routed to it - can akka handle this as well - or does it need to have a discrete port for akka and another for any http interface?

Web Server being used as File Storage - How to improvise?

I am making a DR plan for a web application which is hosted on a production web server. Now that web server also acts as a file storage for storing the feed uploads files (used by the web application as input) and report files( output of web application processing). Now if the web server goes down , the files data is also lost, so need to design a solution and give recomendations which eliminates this single point of failiure.
I have thought of some recommendations as follows-
1) Use a seperate file server however it requires a new resources
2) Attach a data volume mounted on the web server which is mapped to some network filer ( network storage) which can be used to store the feeds and reports. In case the web server goes down , the network filer can be mounted and attached to the contingency web server.
3) There is one more web server which is load balanced however that is not currently being used as file storage , and if we can implement a feature which takes the back up of the file data regularly to that load balanced second web server , we can start using that incase the first web server goes down. The back up can be done through a back up script, or seperate windows service , or some scheduling job for scheduling the backup job every night.
Please help me to review above or suggest new recommendations to help eliminate this single point of failiure problem on the web server. It would be highly appreciated?
Regards
Kapil
I've successfully used Amazon's S3 to store the "output" data of web and non-web applications. Using a service like that is beneficial from the single-point-of-failure perspective because then any other instance of that web application, or a different type of client, on the same server or in a completely different datacenter still has access to the same output files. Another similar option is Rackspace's CloudFiles.
Both of these services are very redundant, and you could use them as the back, and keep the primary storage on your server, or use them as the primary and keep a backup on your other web server. There are lots of options! Hops this info helps.

Switching state server to another machine in cluster

We have a number of web-apps running on IIS 6 in a cluster of machines. One of those machines is also a state server for the cluster. We do not use sticky IP's.
When we need to take down the state server machine this requires the entire cluster to be offline for a few minutes while it's switched from one machine to another.
Is there a way to switch a state server from one machine to another with zero downtime?
You could use Velocity, which is a distributed caching technology from Microsoft. You would install the cache on two or more servers. Then you would configure your web app to store session data in the Velocity cache. If you needed to reboot one of your servers, the entire state for your cluster would still be available.
You could use the SQL server option to store state. I've used this in the past and it works well as long as the ASPState table it creates is in memory. I don't know how well it would scale as an on-disk table.
If SQL server is not an option for whatever reason, you could use your load balancer to create a virtual IP for your state server and point it at the new state server when you need to change. There'd be no downtime, but people who are on your site at the time would lose their session state. I don't know what you're using for load balancing, so I don't know how difficult this would be in your environment.