It is not an uncommon scenario to have a web farm of servers sitting behind a load balancer. In fact that is the only way you can achieve high availability so it is recommended.One issue that arises when this setup is used is when the user session needs to be persisted across all the servers. For example, a request comes in through the load balancer to MachineA. IIS runs the site, a session is created, information is stored in it and the site is appearing functional. Now imagine if something happened to MachineA to take it offline, the load balancer would take it out of rotation and the next request would go to a different machine, which has no knowledge of the previous session and so it would appear to the user as if the site had reset itself or something had gone wrong.
There are many well documented ways to setup shared session state, either using a session state server or a SQL server, but there is one situation where you can run into issues with the session being unreadable by all machines. This can occur when your server farm consists of a mix of IIS6 and IIS7/7.5 machines.
Consider the architecture in the diagram. A request could come in, be served by the first IIS6 box which would create the session and store onto the state server. The next request from the same user could be routed to an IIS7 box, and in this case there is a chance that IIS7 cannot decrypt the session, and you would end up with an error presented to the user.
This is down to the encryption key, decryption key and the encryption method that is set on each server in the machine.config. These need to be the same in order for every server to be read the session.
Also, if you web farm is hosting multiple sites in IIS, there is one more setting that you need to be aware of. In most cases, if you have one website, it will have an application ID of 1 inside IIS, but as you add more sites, the application ID will be mismatched across servers.
The session ID that is used in the session state server is actually a hash of the application id and the user session ID, so if your applications do not have the same application ID inside your IIS instances on all servers, when another server looks up the session, it will fail as it is looking for a session but created with a different ApplicationID.
Setting ApplicationID in IIS7+
To set this in IIS7+, it is very easy. Simply open IIS Manger, and then drill down into your site, and the in the Action Pane, open the “Advanced Settings”. Inside there, there is an ID field. Set this to the same on every server for each site.
Setting ApplicationID in IIS6
The simplest way of doing this is to use the admin scripts:
- Open an elevated command line
- Navigate to your AdminScripts directory (be default in c:\Inetpub\AdminScripts).
- And run this script:
cscript adsutil.vbs move w3svc/999 w3svc/2
(Where the first is the old Site ID and the second is the new one)
The other manual way is to edit the MetaBase.xml, and update the IDs. If you don’t get them all right, the IIS server won’t start, so take care when doing this.
Once all the site ID's and the machine keys are the same, then all your sessions should be available to all systems, irrelevant of OS, IIS version or State Management system.
Hope it helps!