Scott Forsyth's Blog

Postings on IIS, ASP.NET, SQL Server, Webfarms and general system admin.

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.

Posted: Jan 18 2009, 06:48 AM by OWScott | with 8 comment(s) |
Filed under: , ,

Comments

Paul Lynch said:

Hi Scott,

That's a cool suggestion, I'm going to try it out on one of our web farms.

My solution to this problem has always been to modify the default iistart.htm page on each box to include the server name and then just browse that page when I want to know which machine the load balancer has sent me to. Quick and dirty but it works for me ;-)

Cheers,

Paul

# January 20, 2009 5:03 AM

Christopher_G_Lewis said:

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

<ServerName>

# January 20, 2009 11:58 AM

OWScott said:

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.

# January 20, 2009 1:10 PM

Rovastar said:

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.

# January 20, 2009 8:45 PM

OWScott said:

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.

# January 20, 2009 11:05 PM

Christopher_G_Lewis said:

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.

# January 22, 2009 1:54 PM

OWScott said:

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

# January 22, 2009 5:19 PM

DotNetShoutout said:

Thank you for submitting this cool story - Trackback from DotNetShoutout

# January 25, 2009 4:19 AM