Creating a custom advisor
A custom advisor is a small piece of Java™ code, provided as a class file, that is called by the Load Balancer base code to determine the load on a server.
The base code provides all necessary administrative services, including starting and stopping an instance of the custom advisor, providing status and reports, recording history information in a log file, and reporting advisor results to the manager component.
- The Load Balancer base code opens a connection with the server machine.
- If the socket opens, the base code calls the specified advisor's GetLoad function.
- The advisor's GetLoad function performs the steps that the user has defined for evaluating the server's status, including waiting for a response from the server. The function terminates execution when the response is received.
- The Load Balancer base code closes the socket with the server and reports the load information to the manager. Depending on whether the custom advisor operates in normal mode or in replace mode, the base code sometimes does additional calculations after the GetLoad function terminates.
Normal mode and replace mode
You can design custom advisors to interact with the Load Balancer in either normal mode or replace mode.
The choice for the mode of operation is specified in the custom advisor file as a parameter in the constructor method. (Each advisor operates in only one of these modes, based on its design.)
In normal mode, the custom advisor exchanges data with the server, and the base advisor code times the exchange and calculates the load value. The base code then reports this load value to the manager. The custom advisor returns the value zero to indicate success, or negative one to indicate an error.
To specify normal mode, set the replace flag in the constructor to false.
In replace mode, the base code does not perform any timing measurements. The custom advisor code performs whatever operations are specified, based on its unique requirements, and then returns an actual load number. The base code accepts the load number and reports it, unaltered, to the manager. For best results, normalize your load numbers between 10 and 1000, with 10 representing a fast server and 1000 representing a slow server.
To specify replace mode, set the replace flag in the constructor to true.
Advisor naming conventions
Custom advisor file names must follow the form ADV_ name .java, where name is the name that you choose for your advisor. The complete name must start with the prefix ADV_ in uppercase letters, and all subsequent characters must be lowercase letters. The requirement for lowercase letters ensures that the command for running the advisor is not case sensitive.
According to Java conventions, the name of the class defined within the file must match the name of the file.
Compilation
java -fullversion
./java -fullversion
- The custom advisor file
- The base classes file, ibmnd.jar , which is found in the install_path/servers/lib directory
install_path
/java/bin/javac -classpath /opt/ibm/edge/lb/servers/lib/ibmlb.jar ADV_ name
.java
where: - Your advisor file is named ADV_name.java
- Your advisor file is stored in the current directory.
The output of the compilation is a class file, for example, ADV_ name .class. Before starting the advisor, copy the class file to the install_path /servers/lib/CustomAdvisors/ directory.
Running a custom advisor
To run the custom advisor, you must first copy the advisor's class file to the lib/CustomAdvisors/ subdirectory on the Load Balancer machine. For example, for a custom advisor named myping, the file path is install_path/servers/lib/CustomAdvisors/ADV_myping.class
dscontrol advisor start myping port_number
The port number specified in the command is
the port on which the advisor will open a connection with the target
server.Required routines
- A constructor routine. The constructor calls the base class constructor.
- An ADV_AdvisorInitialize method. This method provides a way to perform additional steps after the base class completes its initialization.
- A getLoad routine. The base advisor class performs the socket opening; the getLoad function only needs to issue the appropriate send and receive requests to complete the advising cycle.
Search order
Custom advisors are called after native, or standard, advisors have been searched. If the Load Balancer does not find a specified advisor among the list of standard advisors, it consults the list of custom advisors. Additional information about using advisors is available in the WebSphere® Application Server Load Balancer Administration Guide.
Naming and file path
- The custom advisor must be named in lowercase alphabetic characters in order to eliminate case sensitivity when an operator types commands on a command line. The advisor name must be prefixed with ADV_
- The custom advisor class must be located within the subdirectory lib/CustomAdvisors. The default location for this directory is /opt/ibm/edge/lb/servers/lib/CustomAdvisors on Linux and UNIX systems, and C:\Program Files\IBM\edge\lb\servers\lib\CustomAdvisors\ on Windows systems.
Custom advisor methods and function calls
Constructor (provided by advisor base)
public <advisor_name> (
String sName;
String sVersion;
int iDefaultPort;
int iInterval;
String sDefaultLogFileName;
boolean replace
)
- sName
- The name of the custom advisor.
- sVersion
- The version of the custom advisor.
- iDefaultPort
- The port number on which to contact the server if no port number is specified in the call.
- iInterval
- The interval at which the advisor will query the servers.
- sDefaultLogFileName
- This parameter is required but not used. The only acceptable value is a null string, ""
- replace
- Whether or not this advisor functions in replace mode.
Possible values are the following:
- true – Replace the load calculated by the advisor base code with the value reported by the custom advisor.
- false – Add the load value reported by the custom advisor to the load value calculated by the advisor base code.
ADV_AdvisorInitialize()
void ADV_AdvisorInitialize()
This method is provided to perform any initialization that might be required for the custom advisor. This method is called after the advisor base module starts.
In many cases, including the standard advisors, this method is not used and its code consists of a return statement only. This method can be used to call the suppressBaseOpeningSocket method, which is valid only from within this method.
getLoad()
int getLoad(
int iConnectTime;
ADV_Thread *caller
)
- iConnectTime
- The length of time, in milliseconds, that it took the connection to complete. This load measurement is performed by the advisor base code and passed to the custom advisor code, which can use or ignore the measurement when returning the load value. If the connection fails, this value is set to -1.
- caller
- The instance of the advisor base class where advisor base methods are provided.
Function calls available to custom advisors
The methods, or functions, described in the following sections can be called from custom advisors. These methods are supported by the advisor base code.
Some of these function calls can be made directly, for example, function_name (), but others require the prefix caller. Caller represents the base advisor instance that supports the custom advisor that is being executed.
ADVLOG()
void ADVLOG (int logLevel
, String message
)
- logLevel
- The status level at which the message is written to the log file. The advisor log file is organized in stages; the most urgent messages are given status level 0 and less urgent messages receive higher numbers. The most verbose type of message is given status level 5. These levels are used to control the types of messages that the user receives in real time (The dscontrol command is used to set verbosity). Catastrophic errors should always be logged at level 0.
- message
- The message to write to the log file. The value for this parameter is a standard Java string.
getAdvisorName()
The getAdvisorName function returns a Java string with the suffix portion of your custom advisor's name. For example, for an advisor named ADV_cdload.java, this function returns the value cdload.
This function takes no parameters.
Note that it is not possible for this value to change during one instantiation of an advisor.
getAdviseOnPort()
The getAdviseOnPort function returns the port number on which the calling custom advisor is running. The return value is a Java integer (int), and the function takes no parameters.
Note that it is not possible for this value to change during one instantiation of an advisor.
caller.getCurrentServerId()
The getCurrentServerId function returns a Java string which is a unique representation for the current server.
Typically, this value changes each time you call your custom advisor, because the advisor base code queries all server machines in series.
This function takes no parameters.
caller.getCurrentClusterId()
The getCurrentClusterId function call returns a Java string which is a unique representation for the current cluster.
Typically, this value changes each time you call your custom advisor, because the advisor base queries all clusters in series.
This function takes no parameters.
caller.getSocket()
The getSocket function call returns a Java socket which represents the socket opened to the current server for communication.
This function takes no parameters.
getInterval()
The getInterval function returns the advisor interval, that is, the number of seconds between advisor cycles. This value is equal to the default value set in the custom advisor's constructor, unless the value has been modified at run time by using the dscontrol command.
The return value is a Java integer (int). The function takes no parameters.
caller.getLatestLoad()
The getLatestLoad function allows a custom advisor to obtain the latest load value for a given server object. The load values are maintained in internal tables by the advisor base code and the manager daemon.
int caller.getLatestLoad (String clusterId, int port, String serverId)
The three arguments together define one server object.
- clusterId
- The cluster identifier of the server object for which to obtain the current load value. This argument must be a Java string.
- port
- The port number of the server object for which to obtain the current load value.
- serverId
- The server identifier of the server object for which to obtain the current load value. This argument must be a Java string.
- A positive return value represents the actual load value assigned for the object that was queried.
- The value -1 indicates that the server asked about is down.
- The value -2 indicates that the status of the server asked about is unknown.
This function call is useful if you want to make the behavior of one protocol or port dependent on the behavior of another. For example, you might use this function call in a custom advisor that disabled a particular application server if the Telnet server on that same machine was disabled.
caller.receive()
The receive function gets information from the socket connection.
caller.receive(StringBuffer * response
)
- 0 indicates data was sent successfully.
- A negative number indicates an error.
caller.send()
The send function uses the established socket connection to send a packet of data to the server, using the specified port.
caller.send(String command
)
- 0 indicates data was sent successfully.
- A negative number indicates an error.
suppressBaseOpeningSocket()
The suppressBaseOpeningSocket function call allows a custom advisor to specify whether the base advisor code opens a TCP socket to the server on the custom advisor's behalf. If your advisor does not use direct communication with the server to determine its status, it might not be necessary to open this socket.
This function call can be issued only once, and it must be issued from the ADV_AdvisorInitialize routine.
The function takes no parameters.