With load balancing, the amount of server traffic is divided between two or more computers so that more work gets done in the same amount of time and all online users will generally be served faster. Third-party plugins can be used to provide load balancing capabilities for Sun Java System Web Server. Contact load balancing plugin providers for information about solutions that work with Sun Java System Web Server.
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:
Standard
Base load decisions on the number of queued requests. This is a passive approach. By letting the queue fill up you are already delaying some requests. In this case, you want the HighThreshold to be a low value and LowThreshold to be a high value.
Aggressive
Base load decisions on the number of active threads in the pool. This is designed to more tightly control the requests so that you would reduce the load before requests get queued.
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. |
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.
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.
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
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.
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.
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.
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.
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; }