In this tutorial, you will learn how to configure Umbraco CMS to work within a load-balanced configuration. One of Umbraco's strong points is its power to be hosted in a number of ways, including within a load-balanced set-up. If your website traffic is large and your servers memory or processors capacity is constantly throttling, your most likely fix is to throw my hardware at the problem 💰💰💰
Out-of-the-box, Umbraco is configured to work on a single server, however, you can change this with a few configuration tweaks. There are a few hidden gotchas when configuring Umbraco to work with multiple nodes. If you are not aware of them, it is easy to waste a day or two, wondering whats gone wrong. If you don't fancy two days of debugging and frustration, this is the tutorial for you 🔥🔥🔥
How Should I Setup Umbraco To Work In A Load-Balanced Environment?
Your first consideration when configuring Umbraco to work within a load-balanced environment is how the nodes will share the common resources. Each node will need to point to the same database and use the same connection string, so the database part is simple. How the nodes will share files and media uploaded by the content editors, takes a little more brainpower 🤔
When a content editor uploads some media in Umbraco, it gets stored in the
Media folder. In a load-balanced environment, you need either need both nodes to point to the same location, or, you need to ensure that media is copied to both servers. Otherwise, when a content editor uploads some media, it will be uploaded on one server but not the other and your site visitors will not have a great experience.
To solve this dilemma, we have two options, automatically copy all the files from one server to the other one (replication), or create a shared folder. With a shared folder, when media gets uploaded, all the other sites in your cluster will be able to see the same data. I've used both approaches before and they both work as good as each other. The approach you take will mainly depend on your environment set-up, the budget and what makes you happy ❤️.
Replication: In replication mode, you sync the items within the
media folder between the nodes. The easiest way that I have found to do that, is to use a program called Sugar Sync . You install Sugar Sync upon each server and point it to the folders you want to share (like the media folder). If a change is made on that targetted folder on any of the nodes, they will be synced.
Another popular option is to use Microsoft's DFS (Distributed File System Replication). As I haven't personally used it, I can't personally recommend it, however, I have heard other developers talk positively about it. When deploying Umbraco using file replication, the following folder and file should be excluded from the sync. If you don't do this you will see file locking issues:
When I've used this approach, I've found that the sync can take anything between a few seconds to a few minutes, so there's always a tiny chance someone might see a missing image for a minute or so.
Shared Folder: In a shared folder set-up, you will need to set up a SAN, NAS, Clustered File Server or Network Share. When I've used this approach I've always used a SAN and it works pretty well, although it is not the cheapest option. Within your config, you simply set Umbraco to use the shared drive, simples! You can do this within
FileSystemProviders.config, which you can access here:
Update the media path location, job done 💥
How Do You Make Sure All Umbraco Nodes Are Serving The Same Content?
After you updated all the nodes in your architecture to access the same media files, the next consideration is caching. Umbraco uses a frontend cache to improve performance. This cache uses a combination of a file cache and an in-memory cache. This cache is super useful as it reduces the number of calls Umbraco needs to make to the database, improving page speed. If you want to learn more about how this cache works, I recommend you read thistutorial.
The issue with caching is that unless the cache is synced across the nodes, site visitors will still get different experiences depending on which node they visit. To walk you through a simple example, let's say we have two nodes in the cluster, a content editor uses Umbraco and makes an update to the site on node A. Even though the files are now in sync each server will still be different until all of the nodes caches have been re-built.
Without some sort of notification, how does a different node know when to invalidate the cache? It doesn't, so what is the solution? Getting a developer to refresh the app pool every time someone does some content is not a feasible solution.
Instead, Umbraco has a setting that ensures updates are pushed out to all the servers in your cluster. In order to enable this capability, we need to make each node in the cluster-aware of all the other nodes. When Umbraco is aware of all of the nodes within your cluster, it can push notifications out so that each node knows when to invalidate its cache. These notifications will be triggered whenever a content editor publishes, edits or deletes a page.
To enable this capability, you will need to ensure that only one of the nodes is the 'admin' node. This will be the node where you allow content editors to access the Umbraco backend.
My recommendation when nominating an 'admin' node, is to assign it a sub-domain Url, like
admin.website.com. Within your hosting providers DNS, create the sub-domain and pointed to one of the nodes. For good practice, you should disable access to the backend from all the other nodes. You could do this with a routing rule on the
umbraco segment using the IISRewrite module.
The next step is to tell Umbraco about the other nodes in the cluster. You can do this within
umbracoSettings.config. This file is located within your website's webroot, within the
Config folder. Within
umbracoSettings.config locate an element called
distributedcall. Set the value to
distributedCall section, add the URLs, or the IP address to each node in the cluster. One key part of this process is ensuring each node has a unique hostname or IP address to access. You will need to assign each node a sub-domain, like node1.website.com, node2.website.com. You can't just use the main website URL as the cache will not invalidate correctly.
You also need to make sure that each server is set to use its own local cache. You can enable each node to start using its own cache file, within your
web.config. There is an option called,
umbracoContentXMLUseLocalTemp, set this to
How To Configure Your Umbraco Backend In A Load-Balanced Environment?
Now you have the media files being shared correctly and the cache invalidating correctly, the last part is making sure the Umbraco backend works.
The recommended Umbraco approach is to have two unique sub-domains for each node, like
node2.website.com. On the node, that admin.website.com you do nothing and this is used as the server all content editing is made on. On the server that resolved to node2.website.com you block the 'Umbraco' path. The rule to do this might look something similar to:
This approach is recommended to stop the server from getting out of sync and potential nasty things happening. The reason you should use this approach and not something like a load-balanced affinity strategy is that data corruption if users and using the CMS concurrently. A few examples: Two editors save content at the same time, in Umbraco the last one wins.
In a load balancing environment, there is no guarantee of order so there's potential that a content item can end up without a parent and you'll get YSODsyou can not guarantee the state of the system. Another example,one editor could edit a page on server 1 whilst another user has deleted it on server 2.
In this scenario, due to the lack of order, it's possible a page could get saved minus a parent which will cause the website to blow up. The cache instructions could be in the wrong order and again you can't guarantee the state of the site. Maybe the issue on a single page basis doesn't scare you that much, the more likely scenario is that a content editor deletes a page on one node, while another editor moves a whole section on the second node. As the two things are happening simultaneously on different servers you can't guarantee how the cache will end up.
These issues highlight why you shouldn't use multiple servers to edit your Umbraco content. The configuration is not supported and if you ignore the warning then the stability of your website is at risk when load balancing. If you don't care about this risk because you only have one content editor then it is possible to use a load-balanced environment in an affinity strategy.
In an affinity load-balanced strategy, after a content editor has made an initial connection with the server, the load balancer will always assign that user to the same server on the cluster as long as you keep your browser window open. I've seen this strategy used on low traffic, rarely edited Umbraco sites and I've never seen an issue. In general, I strongly recommend always going with the future-proof recommended approach, which with Umbraco is only allowing content editing on one node.
Another possible approach is to configure the load balancer to favour one server for a
www.website.com/umbraco request, but that depends on your environment. If you want more information about how to set this up, I suggest you look at, How To Change The Umbraco Backend Url.
In today's guide, I've written in detail about the consideration when setting up a load-balanced Umbraco environment. It's a pretty easy thing to set-up but it's definitely not good practice to just treat each website as standalone instances, they need to be set-up to work in a load-balanced environment. Where you use a file replication, or, a shared drive solution, like a SAN, is up to you.
Umbraco will work either way so this is definitely a consideration based on your server set-up. If pressed I would usually recommend a shared resource approach, like a SAN. When you set up Umbraco in a load-balanced environment the backend should be configured to only work from one node ever. If you ignore this rule then the content editors may take your site down. If you only have one content editor this might be a gamble you ant to take, however, setting it up correctly can be done in 10 minutes so it seems a bit silly not to.