help.axcms.netAxinom Logo
Save Save Chapter Send Feedback on Network Load Balancing (NLB) Environment


This article contains step-by-step instructions on how to install PremiumSample on a demo NLB cluster using IIS7. For installing on older IIS versions (IIS5.x, IIS6), please refer to our installation guide and MSDN sources.


Network Load Balancing Overview

Network Load Balancing (NLB) is a clustering technology offered by Microsoft as part of all Windows 2000 Server, Windows Server 2003 and Windows server 2008 family operating systems. NLB uses a distributed algorithm to load balance network traffic across a number of hosts, helping to enhance the scalability and availability of mission critical, IP-based services, such as Web, Virtual Private Networking, streaming media, terminal services, proxy, and so on. 

Network Load Balancing assigns a virtual IP address to the cluster. When a client request arrives at the cluster, this virtual IP address is mapped to the real address of a specific node in the cluster based on configuration settings and server availability. When a server fails, traffic is diverted to another server in the cluster. When the failed node is brought back online it is then re-assigned a share of the load. From a user perspective the load balanced cluster appears to all intents and purposes as a single server represented by one or more virtual IP addresses.

The failure of a node in a cluster is detected by the absence of heartbeats from that node. If a node fails to transmit a heartbeat packet for a designated period of time, that node is assumed to have failed and the remaining nodes take over the work load of the failed server.

Nodes in a Network Load Balanced cluster typically do not share data; instead, each stores a local copy of data. In such a scenario the cluster is referred to as a farm. This approach is ideal for load balancing of web servers where the same static web site data is stored on each node. In an alternative configuration, referred to as a pack the nodes in the cluster all access shared data. In this scenario the data is partitioned in such a way that each node in the cluster is responsible for accessing different parts of the shared data. This is commonly used with database servers, with each node having access to different parts of the database data with no overlap (a concept also known as shared nothing).


More Links About NLB

Network Load Balancing Technical Overview

Network Load Balancing Deployment Guide


NLB Demo Cluster

Our testing NLB cluster contains two Windows Server 2008 machines with two NICs on each of them. One of the NIC (on both servers) is configured to use NLB.

  • TMC-WEB1 - NIC1:, NIC2:
  • TMC-WEB2 - NIC1:, NIC2:
  • NLB cluster Virtual IP:


Description of the Behavior

  • MS Server (MS-SERVER)
    • MS Database
    • MS IIS
    • MS AxCMS.Service 
  • LS Shared Server (LS-SHARED) 
    • LS Database
    • shared Upload an Publish folders
    • LS AxCMS.Service 
    • Session State
  • Node 1 (TMC-WEB1)
    • IIS LS1 
  • Node 2 (TMC-WEB2)
    • IIS LS2

We divided the environments on four servers to show you the flexibility of PremiumSample. It is also possible to, for example, combine MS server and LS shared server together or install databases to an external database cluster server. You can try another approach, but we recommend you to use the current one as we have tested it.

The topology is quite optimal. Only Live System is used by NLB, Live System application files are loaded and executed on the server itself from the local disk. Publish (contains aspx pages) and upload (contains user images and files) folders are accessible via UNC share from the shared server.

Management Server and Publish Service are not included in NLB, because an MS site usually doesn't get such a load that would force it to run in a cluster. Also it is usually a good practice to isolate MS from LS so that editors would not affect visitors and vice versa. Such configuration is also much more secure. Publishing process will place the items to the Shared Server via UNC.

MS and PS web.config files have the unchangeable parameter <add key="PublishDirectory" value="/publish" />. If you were to change it, you would get an exception while accessing your MS environment. Therefore, publish and upload folders for the MS environment should be located strictly under the root MS directory. The system keeps the unpublished items under these directories. For adding MS and PS to NLB it is needed to setup DFS replication among publish and upload folders on all the MS servers in the cluster. Otherwise if you edit a page on some MS server (without publishing), it will not be accessible on another MS server. In this case you would get an exception "Access denied" while trying to open a page for editing on another MS server.

In conclusion, you can move all the parts as you like, but you should avoid:
1) Moving publish and upload folders from the MS environment to another location/server.
2) Using UNC paths for the IIS web sites (only publish and upload folders for LS environment should be mapped as remote UNC virtual directories).



In our demo NLB environment TMC-WEB1 and TMC-WEB2 server names were used as cluster nodes, LS-SHARE as Shared Server and MS-SERVER as Management System server.


Database Installation

Install LS and MS databases like you would in your normal installation.

Refer to the Database installation topic here.


Custom Service Account (Shared User)

For accessing a shared server we should use the same credentials on all servers.

It is possible to use some Active Directory user (if your servers are in a domain) or to create a user with the same credentials on each cluster node, MS server and shared server. Do not assign this user to the Administrators group as it would increase security vulnerability. In our demo NLB a tmc-web user was created on each server (TMC-WEB1, TMC-WEB2, MS-SERVER, LS-SHARE).

To create a new account:

  1. Create a new local or domain user account. Create a local account by using the Computer Management tool in the Control Panel. Create a domain account by using the Active Directory Users and Computers tool in the Control Panel.
  2. Give the account an appropriate name, for example, tmc-web. Clear the User must change password at next logon and select Password never expires.
    Note   Make sure you use a strong password for the account. Strong passwords should include at least seven characters and should be a mixture of uppercase and lowercase letters, numbers, and other characters such as *, ?, or $.


Assign ASP.NET Permissions to the New Account

If you are using a custom service account, the account needs appropriate permissions to access the IIS metabase and the file system folders that are used by ASP.NET. ASP.NET 2.0 provides the Aspnet_regiis.exe utility, which allows you to grant appropriate permissions.

In our case it is needed to do on TMC-WEB1, TMC-WEB2, MS-SERVER and LS-SHARE servers.

To assign ASP.NET permissions to the new account:

  1. In the command window, run the aspnet_regiis -ga MachineName\AccountName command from the %Windir%\Microsoft.NET\Framework\v2.0.50727 (or Framework64, if you have a 64-bit system) folder.

  2. MachineName is the name of your server or the domain name if you are using a domain account, and AccountName is the name of your custom account.

    In our case we run: aspnet_regiis -ga tmc-web.

  3. Review the permissions required by your custom account. When you run Aspnet_regiis.exe with the -ga switch, the command grants the following rights to the account:
  • Access to the IIS metabase.
  • Permission to write to the %Windir%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files folder.

The account is also a member of the local Users group; therefore, it has read access to the \Inetpub directory tree (these directories have an ACL that grants read access to the Users group).

Note   The -ga switch makes a number of global changes. If you want to restrict access to specific folders, you need to manually adjust the ACLs on those folders.


Create an Application Pool with a Custom Identity

With this step, you create a new application pool on all the servers to run your application, and configure it to use the custom service that you created earlier.

To create an application pool that runs using a custom service account:

  1. Start the Internet Information Services (IIS) Manager.
  2. In the left pane, expand the local computer and then expand Application Pools.
  3. Right-click the Application Pools node and then click Add Application Pool.
  4. In the Add New Application Pool dialog box, type the name (we used TMC in demo).
  5. In the .NET Framework version section, choose .NET Framework v2.0.50727.
  6. Managed pipeline mode - starting from 9.0 you can use Integrated mode. If you have an earlier version of, then use Classic.
  7. Right-click on your new Application Pool and select Advanced Settings.
  8. Find the Identity field and assign to it the user you created, with password confirmation.



UNC Share Configuration

If you decide to use UNC shares, we recommend you to configure your PS Application Pool to use custom identity. Otherwise your \\LS_server\upload and \\LS_server\publish paths will be accessible only if they have access to "Everyone", and that is not secure anymore because any Internet user would be able to access it.

  1. First of all you need to create a user in the Domain Controller (if your server is in a domain) or create a user with the same name and password on PS and LS servers. (Control Panel / Administrative Tools / Computer Management / Users / New User...). Do not forget to uncheck the "User must change password at next logon" and select the "Password never expires" option.

  2. Now you need to add appropriate permissions to this user for the PS server only. After that the user can access the IIS metabase and the file system folders that are used by ASP.NET. Never add the user to the Administrators group as it would increase the vulnerability. Go to %Windir%\Microsoft.NET\Framework\v2.0.50727 (or Framework64, if you have a 64-bit system) folder using Command Prompt and run aspnet_regiis -ga MachineName\AccountName

  3. Now add this user to the Application Pool. Go to the Internet Information Services (IIS) Manager. On the left panel, expand the local computer and then expand Application Pools. Find the Application Pool that is used by PS. Right-click it, select Advanced Settings and change the Identity field to new user.

  4. Go to LS server and assign Modify permissions to your created user for publish and upload folders and remove all other unneeded users.

You can just share upload and publish folders without using the Live folder. Just leave a copy of the Live folder on the PS server and assign its local path like it is shown below to the <LiveSystemRootDir> tag. Do not use UNC path to LS root environment here, as you may have problems with remote code excecution permission. If you do this, you have to configure execution permission using the caspol tool (caspol -m -ag 1. -url "file://\\myshare\mydir\*" FullTrust).  

Running PS on the MS server gives you the advantage of hiding it in an internal network, but the disadvantage is that allowing UNC access to LS environment could cause security vulnerability.


Share Publish and Upload folders on the sharing server (in our case, LS-SHARE). Add your shared user with modify permissions to the shared access list.

Grant NTFS access with modify permissions to your shared user under the Security section. All child items should be set to inherit permissions.

You should confirm that you are able to access UNC from cluster servers. In our case, UNC path \\LS-SHARE\Upload and \\LS-SHARE\Publish should be accessible on TMC-WEB1, TMC-WEB2 and MS-SERVER servers via the tmc-web user.


IIS Configuration for Management System

Create an IIS Web Site for the MS environment. Assign it to the previously created Application Pool. On our demo server MS-SERVER it was like this:

Application Pool: TMC
Host name: cms.tmc.axdev
Path: C:\projects\AxCMS_PremiumSample\AxCMSweb_PremiumSample
Templates Virtual Directory: C:\projects\AxCMS_PremiumSample\AxCMSTemplates_PremiumSample

For IIS installation help, refer to the installation topic Getting Started under IIS 7.0.


IIS Configuration for Publish Service

Create an IIS Web Site for the PS environment. Assign it to the previously created Application Pool. On our demo server LS-SHARE it was like this:

Server: LS-SHARE
Application Pool: TMC
DNS: publish.tmc.axdev
Path: C:\projects\AxCMS_PremiumSample\AxCMSPublishService_PremiumSample


IIS Configuration for Live System

Create IIS Web Sites on your cluster servers for the LS environment. Assign them to the previously created Application Pool. On our demo server TMC-WEB1 and TMC-WEB2 it was like this:

TMC-WEB1: web1.tmc.axdev ( - optional
TMC-WEB2: web2.tmc.axdev ( - optional
Cluster: www.tmc.axdev ( (should be added to 'site bindings' for both TMC-WEB1 and TMC-WEB2)
Application Pool: TMC
Path: C:\projects\AxCMS_PremiumSample\AxCMSwebLive_PremiumSample
Templates Virtual Directory: C:\projects\AxCMS_PremiumSample\AxCMSTemplates_PremiumSample
Publish Virtual Directory: \\LS-SHARE\publish
Upload Virtual Directory: \\LS-SHARE\upload

When adding publish and upload Virtual Directories, assign your shared user by clicking Connect As. Afterwards, test the settings by clicking Test Settings and ensure that the test has succeeded like can be seen on the picture below.

NOTE: Do not delete the original publish and upload folders under the site directory structure on your cluster nodes. Just override their paths in IIS Manager by creating new virtual directories. Otherwise you may get an exception: "Directory 'C:\projects\AxCMS_PremiumSample\AxCMSwebLive_PremiumSample\publish' does not exist. Failed to start monitoring file changes".

While expanding publish or upload virtual directories in IIS manager (which have UNC paths) you may get a Login Failure.

Don't panic, IIS configuration is correct. The reason for this is that you are logged in with your personal account (not with the shared one, like tmc-web) and your user account does not match the shared server's one. To solve this issue, just open your server's UNC path, like \\LS-SHARE\Publish, in a browser and log in with the tmc-web credentials. After that, you may refresh IIS sites and freely expand virtual directories which have a UNC path.

Ensure that cluster Host name and IP are added to Site Bindings (host headers) list to every cluster's node. To open the Site Bindings list, right-click on your IIS Web Site (Live environment) and choose Edit Bindings.


Web.config Configurations

The main changes that were made for NLB demo environment:

  • <add key="PublishDir" value="\\LS-SHARE\publish" />
  • <add key="LiveSystemHostName" value="http://www.tmc.axdev" />
  • <add key="LiveSystemVirtualPath" value="" />
  • <add key="CMSApplicationHostName" value="http://cms.tmc.axdev" />
  • <add key="CMSApplicationVirtualPath" value="" />
  • <add key="MediaServerHostName" value="http://cms.tmc.axdev" />
  • <DocumentsDir>\\LS-SHARE\upload</DocumentsDir>
  • <PublishDir>\\LS-SHARE\publish</PublishDir>

All the paths in Web Services (MS web.config) were replaced like this:

  • <Url>http://publish.tmc.axdev/UserWebService.asmx</Url>

Session State

ASP.NET session state enables you to store and retrieve values for a user as the user navigates the ASP.NET pages in a Web application. 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 retain variable values for the duration of that session.

You should configure Session State on NLB; otherwise, switching the servers will force users to start browsing from scratch.

Starting from AxCMS.NET version 8.6 it is possible to store ASP.NET Session State in SQL Server.

The following command creates a database named ASPState on a SQL Server instance named "SampleSqlServer" and specifies that session data is also stored in the ASPState database.
aspnet_regsql.exe -S SampleSqlServer -E -ssadd -sstype p

To switch ASP.Net to use SQL you must update the <sessionState> element of your application's Web.config file as follows:

  • Set the mode attribute of the <sessionState> element to SQLServer.
  • Set the sqlConnectionString attribute to specify the connection string to your SQL Server.
  • If you specify integrated security/trusted connections in the database connection string (ie. "trusted_connection=true", or "integrated security=sspi"), you cannot use impersonation in, as your database connection will then run the context of the impersonated user, which will not have rights to the state database. You can, of course grant connections to that user context. KB 326606 has more details.
  • If your web servers are under heavy load it may be useful to increase the time out for session state access. You can add the stateNetworkTimeout attribute to the sessionState settings.
    <sessionState stateNetworkTimeout="15" /> . If a Web server or a state server is under stress and cannot complete session accesses on time, event ID 1072 and event ID 1076 may be logged in the event log.

For example

  sqlConnectionString="data source=server;user id=uid;password=pwd"
  cookieless="false" timeout="20" />

ASP.NET SQL Server Registration Tool (Aspnet_regsql.exe)

HOW TO: Configure SQL Server to Store ASP.NET Session State


Machine Key Validation

You may get an exception “Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.“ while NLB is switching to another server.

There are 2 solutions:

  1. It is possible to turn off the machine key validation by adding <pages enableViewStateMac="false" />  under <system.web> in your LS web.config file (search it for "<pages") on all cluster nodes. But this will increase vulnerability.
  2. A better solution would be to generate a machine validation key and add it under <system.web> in your LS web.config, so that all nodes would use the same key. For example:

    validationKey="6C7EA99D5E7C215C8E2F1A9D91CA7ABE9C4ECCE0CD575744D4956A9564667304D40ABE68BBCE815318744BDF849D9490B8C99E463873AB67B715AD2E20727B2F" decryptionKey="1B2C0DCAB5C1C636054C9B0100B05341E34EA7C743537D4A"      



AxCMS.Service installation procedure is the same as described in the guide.

Just keep in mind that the service should run on a server that has workable publish and upload folders. In our case, we have two servers with active publish and upload folders:

  • MS-SERVER where publish and upload folders are used for the MS environment
  • LS-SHARE where publish and upload folders are used for the LS environments

This means that we should have two AxCMS.Services installed for both environments. The installation can look like this:

  1. On MS-SERVER, configure the appropriate AxCMS.Service.exe.config file and install the service by running register.bat. Here is a snapshot of configuration file:
      <ServiceInstance name="PremiumSample_MS">
       <Context path="/" site="TMC - AxCMS - MS - cms.tmc.axdev ("/>
       <Settings threadCount="5" sleepTime="10" errorSleepTime="60" />
  2. AxCMS.Service should use the IIS site configured on the local machine for getting the configuration from. For that reason we have to create a fake IIS LS site on the LS-SHARE server for the LS environment. We cannot configure AxCMS.Service on NLB cluster nodes as they do not have publish and upload folders locally stored. So we need to create a fake IIS site on the LS-SHARE server, configure AxCMS.Service.exe.config and run register.bat. Here is a snapshot of the configuration file:
      <ServiceInstance name="PremiumSample_LS">
       <Context path="/" site="TMC - AxCMS - fake LS ("/>
       <Settings threadCount="5" sleepTime="10" errorSleepTime="60" />