Do the following on every Real Server in a Virtual Service before selecting adaptive scheduling on the Virtual Service:

  1. Deploy an HTTP server whose endpoint (IP address and port) is accessible to the LoadMaster.

  2. Write and install a 'server agent' that runs periodically and does the following:

    1. The agent queries the server operating system for system load statistics.
    2. The agent then uses the load values obtained from the operating system to arrive at an integer value indicating the system load. Under normal circumstances, this will be an integer between 1 and 100 with higher numbers indicating a higher load. Other integers can be returned for special conditions (see the table below).
    3. Finally, the agent places the integer value (and nothing else) in a file underneath the root directory of the HTTP server running on the Real Server.

If the application is OK and ready to service requests, set the Real Server load value in the file returned by the HTTP server to the same integer value (1-100) on each server, for example, 50. This will result in a round-robin between the servers. If the servers have different levels of resources, set them higher or lower as appropriate.

If the application is down, set the Real Server load number to 101. This marks the server as down in the User Interface (UI).

Note: When you first enable adaptive scheduling and there is no HTTP server running on the Real Server, the Real Server weight is set to 100 (heavily loaded).

On the LoadMaster side, you can then select adaptive scheduling on the Virtual Service, which enables the following behavior:

  • The LoadMaster periodically performs an HTTP GET to retrieve the file populated with the integer load value from each Real Server in the Virtual Service.

  • Until the LoadMaster successfully retrieves an integer load value from a Real Server, it is considered unavailable (dynamic weight = 0).

  • Once a load value is obtained for a Real Server, the LoadMaster modifies the dynamic weight of the Real Server, according to the table below.

Agent Response Action Taken Description
No HTTP Response Dynamic Weight = 0 If the LoadMaster gets no response when it attempts to get the file containing the load value, then the Real Server is assumed to be unavailable and it is marked down. This is done by setting the server's dynamic weight to 0 so that no new connections are sent to it. Currently open connections are not affected. This typically happens when either the Real Server is unavailable, or the required HTTP server is not responding to the query from the LoadMaster.
File does not exist Dynamic Weight = 100 If the HTTP server is running on the Real Server and responds to the LoadMaster's query, it may send a response that indicates the file requested does not exist. In this case, the server is assumed to be available, it is marked up, and the server dynamic weight is set to 100.
File is empty Dynamic Weight = 100 If the HTTP server is running on the Real Server and responds to the LoadMaster’s query with an empty file (the file contains no data at all), the server is assumed to be available. It is then marked up and the server dynamic weight is set to 100.
File contains a non-integer value Dynamic Weight = 100 If the file returned by the HTTP server running on the Real Server contains a non-integer value, then the server is assumed to be available. It is then marked up and the server dynamic weight is set to 100.
< 0 Dynamic Weight = 100 If the file returned by the HTTP server running on the Real Server contains a negative integer value (for example, -1), then the server is assumed to be available, it is marked up, and the server dynamic weight is set to 100.
0 Switch to the round robin scheduling method If the file returned by the HTTP server running on the Real Server contains an integer value of 0 (zero), this forces the LoadMaster to temporarily fall back to using the round robin scheduling method until the server agent returns a value other than 0 on a subsequent query. This return value is intended to be used in a situation where the server agent code cannot for some reason arrive at a valid integer value to return to the LoadMaster. This might happen if, for example, the server is not responding to the queries from the agent for load values.
1-100 Dynamic Weight set appropriately

If the file returned by the HTTP server running on the Real Server contains an integer value between 1 and 100, this is interpreted as a percentage of fully loaded (1=lowest load, 100 = fully loaded). The LoadMaster sets the dynamic weight appropriately: the higher the number returned by the server agent, the lower that the dynamic weight of the server is set to.

The value 100 represents that the server's actual load is below 90% (as per the sample script) therefore the LoadMaster is sending a percentage of requests to the server. The scripts provided in this document are sample scripts and it is up to you in which situation you want to stop sending new traffic to the loaded server by setting load values to either 101 or 102. To avoid a situation where a server reporting 100 still gets a percentage of requests, you should modify the script so that it returns 101 or 102 if the server is fully loaded by your definition. For example, you can configure the script that 101 load value is returned when the actual load on the server is >=80%.

101 Dynamic Weight = 0 If the file returned by the HTTP server running on the Real Server contains an integer value of 101, the server is considered to have reached its maximum load and it is marked as down. The server dynamic weight is set to 0 so that no new connections are sent to it. Only the active connections are served and no new connections are directed to this server.
102 Dynamic Weight = 0 plus optional connection drop If the file returned by the HTTP server running on the Real Server contains an integer value of 102, this means essentially the same as returning 101. The only difference is that the LoadMaster will also drop all currently open connections if the Drop connections on RS failure option is set on the associated VS.
> 102 Dynamic Weight = 0 A return of 103 or greater is treated the same as a return of 101.

On any Real Server operating system, a straightforward manner in which to implement a server agent is to write a shell script or executable program that runs periodically using a standard system scheduler, like cron on Linux systems or the Task Scheduler on Windows systems. This script would use standard utilities to generate the load value and place it in a file under the HTTP server root.

Such a script could be as simple as this Linux bash script:

#! /bin/bash
top –l1 | awk ‘/CPU Usage/ {printf “%d\n”, $7} > /<path>/load

The above uses the top command and a short awk script to copy the current CPU load value in a file – the <path> above specifies the path to the root of an HTTP server on the Real Server. The file name ‘load’ is the default file name retrieved by the LoadMaster. [This and other adaptive load balancing options are located in the User Interface (UI) under Rules & Checking > Check Parameters > Adaptive Parameters.]

Alternatively, you could instead write a Common Gateway Interface (CGI) program or any other program that the HTTP server can be configured to run when the LoadMaster sends a GET for the required file to the HTTP server. This program would generate the integer load value when the LoadMaster requests the file from the server and the HTTP server would return it to the LoadMaster.

There are advantages and disadvantages to either approach. For example:

  • Using a static file populated using a cron job is a simple and easy-to-maintain option, but also means that the data in the file could be stale when it is accessed by the LoadMaster. The interval at which the load value is generated should be based on the known performance profile of the server.
  • Using a program that runs each time the LoadMaster checks performance means that you will get the most accurate data, but the server agent itself could contribute to system load if CPU, Disk I/O, and network performance were all being continually checked by the server agent.

The approach you choose most likely depends on the needs of your configuration and the tools you typically use.

In terms of internal processing, a server agent can be as complicated as you like, depending on your application. If your application is completely CPU-intensive, then a simple script like the two-line bash script above may be enough. But, if your application also generates significant disk I/O or network-traffic, you will probably want to consider the load on those resources in addition to CPU usage to get a more detailed view of server performance.