Moving the Unmovable App...

·

4 min read

I am often in a situation where I am helping customers to move applications from a data center to AWS. Many of these applications have been developed in-house and suffer from various amounts of technical debt. In-house applications are oftentimes developed quickly to fill a specific functional gap and rarely have the luxury of extensive design or architecture work.

Customers who want to migrate to the cloud often fear that some of these applications may be "unmoveable" due to less-than-optimal coding practices. I have had conversations with customers who say things like, "That application can't be moved.", "It's impossible to run more than one instance of that application." or "The application will break if we move it to the cloud."

One of the most common reasons customers believe they can not move an ASP .NET application to AWS is that the application relies on the session state to maintain the state of the currently logged-in user. ASP .NET and ASP .NET Core applications are commonly built from default templates where the session state is stored in memory on the server. This is convenient and requires no additional setup by the developer. However, it means that the application assumes it is running on a single server.

For example, consider this very basic code snippet:

if (Session["count"] == null)
    Session["count"] = 0;
else
    Session["count"] = (int)Session["count"] + 1;

The first time a user executes the code, the number 0 will be stored in the user session. Each subsequent time the user executes this code, the number will increase. This code is very basic, but similar code exists in thousands, if not millions, of internal .NET Framework applications written in the past twenty years.

Everything is fine as long as this application only runs on a single server. However, things start going wrong if we implement high availability by running two copies of the application through a load balancer.

Single Server Deployment

Consider the code above, if we deploy that code to a single server environment and load a web page we get the following:

Each time the page is reloaded during a session, the Session Counter will increase by one.

Setting up a Multi-Server deployment

Next, update the deployment architecture to include a second server and an application load balancer.

In this case, incoming traffic will be routed to the application load balancer. The load balancer will then perform round-robin routing between the two instances. This creates the issue the customer was concerned about.

As you can see from the video above, the Session Counter is jumping up and down. This is because each of the servers that the application is running on maintains its session state. (Ignore the fact that the Host Name is not changing on the application. I cloned the EC2 instance for this example, so both instances have the same hostname.)

Correcting the issue

There are multiple ways that a customer can correct the issue. The best way is to update the application to store the session state off the local server so that each instance can retrieve the session information from a cache. This option provides the greatest level of flexibility.

However, updating the application logic and redeploying your application will require development effort. In some cases, additional development effort is either impossible or not practical. You may want to implement a simple workaround as a temporary fix in these cases.

In the AWS, select the EC2 service. From there, click "Load Balancers" in the left-hand navigation panel.

Select your load balancer from the list

Locate the target group for the specific routing rule that you are using

Select the Attributes tag and then click edit.

Under target selection configuration, click to enable "Turn on stickiness."

Leave the other options selected as default and click "Save Changes."

Enabling stickiness will mean the load balancer can still route calls between the different EC2 instances. However, once a particular session has been routed to a specific instance, the load balancer will continue to route calls to that instance. (If that instance is available)

In practice, this means that applications dependent on the session state will still behave exactly as they did previously while benefiting from the resiliency of having multiple instances behind a load balancer.

If you return to the web page, you can see that with sticky sessions, the web application counter no longer jumps around. This is because the session is being routed to the same EC2 instance.

Conclusion

Enabling sticky sessions is an easy and immediate workaround that will help you move those "unmoveable" applications from a data center into the cloud and help you get some basic high availability in place without making code changes.

For simple applications or applications with a very short runway to retirement, sticky sessions may be a valid permanent solution. For other applications, you should plan further updates. These updates should include modernizing away from the .NET Framework (If applicable) and updating the application to store the session state externally.

Did you find this article valuable?

Support Tom Moore by becoming a sponsor. Any amount is appreciated!