Sun Java System Web Server 6.1 SP9 Performance Tuning, Sizing, and Scaling Guide

Using libloadbal

You can use the load balancing plugin libloadbal to allow your server to execute a program when certain thread load conditions are met, so a load distribution product on the front-end can redistribute the load.

There are two methods that you can use to trigger the load balancer to increase or decrease load:

Library configuration

To enable the plugin, you must modify magnus.conf manually. This should look something like this:

Init fn="load-modules" funcs="init-resonate"
shlib="server_root/bin/https/lib/libloadbal.so"
Init fn="init-resonate" ThreadPool="sleep" 
EventExePath="/tools/ns/bin/perl5" LateInit="yes" 
CmdLow="/opt/SUNWwbsvr/plugins/loadbal/CmdLow.pl" 
CmdHigh="/opt/SUNWwbsvr/plugins/loadbal/CmdHigh.pl"

The init-resonate function can take the following parameters:

Table 3–1 init-resonate Parameters

Parameter  

Description  

ThreadPool

Name of the thread pool to monitor. 

Aggressive

If set to TRUE, this argument causes the plugin to use the pool thread count rather than the queue thread count.

PollTime

How frequently to check the thread status. The default is 2000 milliseconds. 

HighThreshold

Defines the queue size/# of threads where HighCmd is executed to increase load on the server. The default is 4096.

LowThreshold

Defines the queue size/# of threads where the LowCmd is executed to decrease load on the server. The default is 1.

EventExePath

Pointer to the script program you want to run (for instance, /usr/bin/perl or /bin/sh). Defaults to perl or perl.exe, depending on the platform.

CmdLow

Pointer to the script to be run when the LowThreshold is met.

ArgsLow

Arguments to send to CmdLow.

CmdHigh

Pointer to the script to be run when the HighThreshold is met.

ArgsHigh

Arguments to send to CmdHigh.


Note –

You must specify LateInit="yes" when loading this module. The module creates a monitoring thread, and this monitoring thread must start after ns-httpd has started.


If you set LogVerbose on in magnus.conf, the error log contains information on how the plugin is configured and when it is invoked.

A sample of the information in the error log is shown below:

[12/Jun/2003:09:36:35] verbose (20685): Resonate plugin watching 
thread pool sleep
[12/Jun/2003:09:36:35] verbose (20685): Resonate plugin 
aggressive setting is FALSE
[12/Jun/2003:09:36:35] verbose (20685): Resonate plugin poll time 
set to 2000
[12/Jun/2003:09:36:35] verbose (20685): Resonate plugin 
HighThreshold set to 5
[12/Jun/2003:09:36:35] verbose (20685): Resonate plugin 
LowThreshold set to 1
[12/Jun/2003:09:36:35] verbose (20685): Resonate plugin event 
executable path set to /tools/ns/bin/perl5
[12/Jun/2003:09:36:35] verbose (20685): Resonate plugin low 
command set to /opt/SUNWwbsvr/plugins/loadbal/CmdLow.pl
[12/Jun/2003:09:36:35] verbose (20685): Resonate plugin high 
command set to /opt/SUNWwbsvr/plugins/loadbal/CmdHigh.pl

This is what the log entries will look like when LogVerbose on is set and the plugin is activated:

[12/Jun/2003:09:40:12] verbose (20699): Resonate plugin reducing load.
 [12/Jun/2003:09:40:14] verbose (20699): Resonate plugin reducing load.
 [12/Jun/2003:09:40:16] verbose (20699): Resonate plugin reducing load.
 [12/Jun/2003:09:40:18] verbose (20699): Resonate plugin reducing load.
 [12/Jun/2003:09:40:20] verbose (20699): Resonate plugin reducing load.
 [12/Jun/2003:09:40:30] verbose (20699): Resonate plugin increasing load.

Testing

To test the load balancer, you can create an NSAPI plugin that prints an HTML page and then calls sleep() for a period to simulate execution time. This way you can build up a simulated load on the server and ensure that the load balancer commands are working properly.

ProcedureTo configure the sample program

  1. Add a new mime.type so this isn't run for every request by modifying config/mime.types and adding:

    type=magnus-internal/sleep exts=sleep

  2. Create a file in your document root directory with the extension of .sleep.

    It does not matter if anything is in this file; it is used only as a placeholder.

  3. Load the module into the server by editing magnus.conf.

    Init fn="load-modules" funcs="dosleep" shlib="/opt/SUNWwbsvr/plugins/nsapi/examples/dosleep.so" pool="sleep"

    In the example above, you are changing shlib to the location of the library, and setting pool to the name of the thread pool you defined earlier.

  4. Add this Service line where the others are found (note that order is not important):

    Service method="(GET|HEAD)" fn="dosleep" duration="10" type="magnus-internal/sleep"

    The argument duration tells the server how long to sleep for each request in seconds.

  5. Restart your server.

    You should now be ready to test the load balancer plugin. The NSAPI plugin will keep the threads busy long enough to simulate your desired load. The load balancing plugin is tested by retrieving the .sleep file you created earlier.

Sample

Below is a sample dosleep.c:

#ifdef XP_WIN32
#define NSAPI_PUBLIC __declspec(dllexport)
#else /* !XP_WIN32 */
#define NSAPI_PUBLIC
#endif /* !XP_WIN32 */

#include "nsapi.h"

#define BUFFER_SIZE 1024

#ifdef __cplusplus
extern "C"
#endif
NSAPI_PUBLIC int dosleep(pblock *pb, Session *sn, Request *rq)
{
    char buf[BUFFER_SIZE];
    int length, duration;
    char *dur = pblock_findval("duration", pb);

    if (!dur) {
        log_error(LOG_WARN, "dosleep", sn, rq, "Value for duration 
                  is not set.");

        return REQ_ABORTED;
    }

    duration = atoi(dur);

    /* We need to get rid of the internal content type. */
    param_free(pblock_remove("content-type", rq->srvhdrs));
    pblock_nvinsert("content-type", "text/html", rq>srvhdrs);

    protocol_status(sn, rq, PROTOCOL_OK, NULL);

    /* get ready to send page */
    protocol_start_response(sn, rq);

    /* fill the buffer with our message */
    length = util_snprintf(buf, BUFFER_SIZE, 
"<title>%s</title><h1>%s</h1>\n", "Sleeping", "Sleeping");
    length += util_snprintf(&buf[length], BUFFER_SIZE - length, 
"Sample NSAPI that is sleeping for %d seconds...\n", duration);

    /* write the message to the client */
    if (net_write(sn->csd, buf, length) == IO_ERROR)
    {
        return REQ_EXIT;
    }
    sleep(duration);
    return REQ_PROCEED;
}