Web Farms - How to tell which node is being served

I work with web farms on a daily basis, and one of the requirements that I run into, for testing, troubleshooting and logging, is to tell which node is handling a specific request. 

To use a current example, at ORCS Web, we're testing Microsoft's new Application Request Routing Module (ARR) for performance, stability and features to see if it offers value along-side our other load balancing solutions.  (Note: ARR is still in RC1 at the time of this writing)  During testing, I want to be able to tell how ARR is distributing the load under different settings.  Does a custom round robin setting really work as promised?  Does the least current requests work?  How can I tell and test?  Etc, etc.

One simple but important piece of information that I want to see over and over is which server node is being served.  Without knowing the server name of the web node, it's just a guessing game, and the testing is pretty useless.

Fortunately the solution is trivial in ASP.NET.  There are multiple ways to do it, but two namespaces that expose the machine name are System.Environment and System.Web.HttpContext.Current.Server. 

To create a testing page that exposes the server name in VB.NET, create a file called CurrentNode.aspx with the following in it:

<%
Response.Write (System.Environment.MachineName)
%>

Or, if you're using C#, the only difference is the ; (semi-colon) requirement on the end:

<%
Response.Write (System.Environment.MachineName);
%>

That is literally all that I put in the file, or else I tack this on the bottom of an existing page.  You'll notice that it's not valid HTML and nothing fancy, but no common browsers will complain, this is something that I can memorize and quickly type, and it's fully functional.

The computer name is obtained by Windows on system boot-up by reading the registry value.

I'm not aware of any differences in functionality, but you can use the following instead:

<%
Response.Write (HttpContext.Current.Server.MachineName)
%>

Hit that page from the load balancer's IP (often called a VIP [virtual IP]) and you'll know which node is handling the request.

This comes in useful for troubleshooting failures too.  You may have users saying that they are receiving errors on your site, but you're unable to reproduce it consistently.  Expose the server name in your error logging so that you know if it's something specific to particular nodes, or if it's global across all nodes.

10 Comments

  • We've actually gone with adding a custom header item at the server level rather than adding to a site - much easier to implement and no code to change.

    Headers are then visible with WFetch or Fiddler on *all* objects, and never can mess with code.

    You can either do this in IIS Manager at the Web Sites folder - Select properties and change to the HTTP Headers tab. Click Add in the custom header section and enter:

    X-ServerName



  • Hi Paul. That works too. It's manual, but it does the trick.

    Christopher, that's a great idea. As you mention, it requires WFetch, Fiddler or a similar tool to read the headers, but then it's available on all requests. It's easy to implement and doesn't have any real performance impact.

  • Nice tips I think I will be altering the http headers on some of my farms.

    Sort of related often it can be problematic to 'force' yourself onto a particular server in the farm for troubleshooting. If the infrastructure allow I like to assign additional hostheaders to the sites on the servers in the farm and alter my own local host file to have alternative headers for the separate servers. And add the relevant info to the frontend routers/load balancers so they direct the traffic to the right box.

    e.g.
    Additional host header

    serverA.mysite.com
    123.123.123.123

    local host
    serverA.mysite.com
    123.123.123.123
    serverB.mysite.com
    123.123.123.123

    That way I can access a particular server in the farm from anywhere as long as I have changed my local hosts file and other cannot access the box unless they know what to change in the local hosts file.

  • Rovastar. That is a good point. It's important to be able to hit certain nodes specifically when you need to. Your solution works well and is a method to hide access to individual nodes so that people don't start picking on one node or another, while still giving you the ability to test individual nodes when you need to.

  • We always use secondary URLs - primarily because I
    don't trust 3DNS and BigIP :-)

    We also use lanes (PROD, CONTingency, UAT, DEV etc) to enforce code promotion standards.

    We use this schema -

    URL: Site.Bank.com
    Alt: Site-Prod.Bank.com

    City/DataCenter URLs are used to bypass geographic DNS.
    * City A: Site-PRODA.Bank.com
    * City B: Site-PRODB.Bank.com

    With a City/DataCenter, Node # is used to bypasses BigIP/NLB:
    * Node 1: Site-PRODA1.Bank.com
    * Node 2: Site-PRODA2.Bank.com
    * Node 3: Site-PRODA3.Bank.com
    * Node 4: Site-PRODA4.Bank.com

    This allows us to touch a single node w/in a City. Note that this is repeated for the contingency sites, so you can check for site availability before switching over to contingency.

  • Christopher, you have a fun situation there. Once you get into geo-specific load balancing, you add a another dimension to the mix.

  • Great Article. We have multiple web farms and use BigIP for the load-balancing and creating a custom header on each Node seems to be a perfect solution for us. Two questions thou.

    1.) Does it matter of the naming schema on the custom header.
    2.) Will it require a reset of IIS, main concern is will I need to schedule downtime for the servers.

  • Hi GeoAndy,

    The name for the customer header doesn't matter, although the X-{something} is the common naming format.

    Note that going with the customer header means that the servers (IIS) can't sync with either other automatically or the customer header will not be unique per server. That means that it won't work for many situations.

    Making a change to the header settings in IIS7 causes an appdomain recycle since it touched your site's web.config file. Here's a recent video blog on understanding AppDomains: http://weblogs.asp.net/owscott/archive/2011/03/19/asp-net-appdomain-what-it-is-and-why-it-s-important-part-12-of-52-part-series.aspx

    I'll write a blog post later today (probably) on another solution to take this a step further to add a permanent way to provide this information on a webfarm.

  • Hi Scott,

    Exist any way to redirect all my request to one specific server? Sometimes we know that a customer has an error but my request are been redirected to another node.

  • Hi Oscar,

    Your load balancer should allow you to do this. The common terms used for that are 'sticky sessions' or 'client affinity'. That will allow users to always return to the same node.

Comments have been disabled for this content.