The Health Monitoring capabilities (as described in Feature Brief: Health Monitoring in Traffic Manager) are very comprehensive, and the built-in templates allow you to conduct sophisticated custom dialogues, but sometimes you might wish to resort to a full programming language to implement the tests you need.
Particularly on the Traffic Manager Virtual Appliance, your options can be limited. There's a minimal Perl interpreter included (see Tech Tip: Running Perl code on the Traffic Manager Virtual Appliance), and you can upload compiled binaries (Writing a custom Health Monitor in C) and shell scripts. This article explains how you can use TrafficScript to implement health monitors, and of course with Java Extensions, TrafficScript can 'call out' to a range of third-party libraries as well.
We'll implement the solution using a custom 'script' health monitor. This health monitor will probe a virtual server running on the local Traffic Manager (using an HTTP request), and pass it all of the parameters relevant to the health request.
A TrafficScript rule running on the Traffic Manager can perform the appropriate health check and respond with a 'PASS' (200 OK) or 'FAIL' (500 Error) response.
The health monitor script is straightforward and should not need any customization. It will take its input from the health monitor configuration.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#!/bin/sh if 0; #!/usr/bin/perl #line 7 BEGIN{ # Pull in the Traffic Manager libraries for HTTP requests unshift @INC , "$ENV{ZEUSHOME}/zxtmadmin/lib/perl" , "$ENV{ZEUSHOME}/zxtm/lib/perl" ; } use Zeus::ZXTM::Monitor qw( ParseArguments MonitorWorked MonitorFailed Log ); use Zeus::HTMLUtils qw( make_query_string ); use Zeus::HTTP; my %args = ParseArguments(); my $http = new Zeus::HTTP( GET => $url ); $http ->load(); Log ( "HTTP GET for $url returned status: " . $http ->code() ); if ( $http ->code() == 200 ) { MonitorWorked(); } else { MonitorFailed( "Monitor failed: " . $http ->code() . " " . $http ->body() ); } |
Upload this to the Monitor Programs of the Extra Files section of the catalog, and then create an "External Program Monitor" based on that script. You will need to add two more configuration parameters to this health monitor configuration:
Your configuration should look something like this:
Create an HTTP virtual server listening on the appropriate port number (vsport). You can bind this virtual server to localhost if you want to prevent external clients from accessing it.
The virtual server should use the 'discard' pool - we're going to add a request rule that always sends a response, so there's no need for any backend nodes.
The 'business end' of your TrafficScript health monitor resides in the TrafficScript rule. This rule is invoked every time the health monitor script is run, and it is given the details of the node which is to be checked.
The rule should return a 200 OK HTTP response if the node is OK, and a different response (such as 500 Error) if the node has failed the test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
$path = http.getPath(); # Use 'path' if you would like to publish # several different tests from this rule $ip = http.getFormParam( "ipaddr" ); $port = http.getFormParam( "port" ); $nodename = http.getFormParam( "node" ); # We're going to test the node $nodename on $ip:$port # # Useful functions include: # http.request.get/put/post/delete() # tcp.connect/read/write/close() # auth.query() # java.run() sub Failed( $msg ) { http.sendResponse( 500, "text/plain" , $msg , "" ); } # Let's run a simple GET $req = 'GET / HTTP/1.0 Host: www.riverbed.com '; $timeout = 1000; # ms $sock = tcp. connect ( $ip , $port , $timeout ); tcp. write ( $sock , $req , $timeout ); $resp = tcp. read ( $sock , 102400, $timeout ); # Perform whatever tests we want on the response data. # For example, it should begin with '200 OK' if ( ! string.startsWith( $resp , "HTTP/1.1 200 OK" ) ) { Failed( "Didn't get expected response status" ); } # All good http.sendResponse( 200, "text/plain" , "" , "" ); |
Hi, I've having a hard time getting this to work. I'm using a developer Virtual Appliance v9.2.
I followed your guidelines and activated verbose on the monitor. I get "Can't open" errors on the log but both webservers are online... I checked the "Running Perl code on the Stingray Virtual Appliance" and the beginning of your perl script isn't exactly the same... Tried with that and get "No such file or directory" error...
Any ideas?