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

Using Statistics to Tune Your Server

This section describes the information available through the perfdump utility, and discusses how to tune some parameters to improve your server’s performance.

The default tuning parameters are appropriate for all sites except those with very high volume. The only parameters that large sites may regularly need to change are RqThrottle, MaxKeepAliveConnections, and KeepAliveTimeout, which are tunable from magnus.conf and the Server Manager.

The perfdump utility monitors statistics in the following categories, which are described in this section:


Note –

For general information about perfdump, see Monitoring Current Activity Using the perfdump Utility


Once you have viewed the statistics you need, you can tune various aspects of your server’s performance using:

Connection Queue Information

Connection queue information shows the number of sessions in the queue, and the average delay before the connection is accepted.

Following is an example of how these statistics are displayed in perfdump:

ConnectionQueue:
----------------------------------
Current/Peak/Limit Queue Length     0/0/4096
Total Connections Queued            0
Average Queueing Delay              0.00 milliseconds

Current /Peak /Limit

Current/Peak/Limit queue length shows, in order:

Tuning

If the peak queue length is close to the limit, you may wish to increase the maximum connection queue size to avoid dropping connections under heavy load.

You can increase the connection queue size by:

Total Connections Queued

Total Connections Queued is the total number of times a connection has been queued. This includes newly accepted connections and connections from the keep-alive system.

This setting is not tunable.

Average Queuing Delay

Average Queueing Delay is the average amount of time a connection spends in the connection queue. This represents the delay between when a request connection is accepted by the server and when a request processing thread (also known as a session) begins servicing the request.

This setting is not tunable.

Listen Socket Information

The following listen socket information includes the IP address, port number, number of acceptor threads, and the default virtual server for the listen socket. For tuning purposes, the most important field in the listen socket information is the number of acceptor threads.

You can have many listen sockets enabled for virtual servers, but at least one will be enabled for your default server instance (usually http://0.0.0.0:80).

ListenSocket ls1:
------------------------
Address                   http://0.0.0.0:8080
Acceptor Threads          1
Default Virtual Server    https-iws-files2.red.iplanet.com

Tuning

You can create listen sockets through the Server Manager, and edit much of a listen socket’s information. For more information about adding and editing listen sockets, see the Sun Java System Web Server 6.1 SP9 Administrator’s Guide.

If you have created multiple listen sockets, perfdump displays all of them.

Set the TCP/IP listen queue size for all listen sockets by:

Address

The Address field contains the base address that this listen socket is listening on. It contains the IP address and the port number.

If your listen socket listens on all IP addresses for the machine, the IP part of the address is 0.0.0.0.

Tuning

This setting is tunable when you edit a listen socket. If you specify an IP address other than 0.0.0.0, the server will make one less system call per connection. Specify an IP address other than 0.0.0.0 for best possible performance.

For more information about adding and editing listen sockets, see the Sun Java System Web Server 6.1 SP9 Administrator’s Guide.

Acceptor Threads

Acceptor threads are threads that wait for connections. The threads accept connections and put them in a queue where they are then picked up by worker threads. Ideally, you want to have enough acceptor threads so that there is always one available when a user needs one, but few enough so that they do not provide too much of a burden on the system. A good rule is to have one acceptor thread per CPU on your system. You can increase this value to about double the number of CPUs if you find indications of TCP/IP listen queue overruns.

Tuning

You can tune this number through the user interface when you edit a listen socket.

For more information about adding and editing listen sockets, see the Sun Java System Web Server 6.1 SP9 Administrator’s Guide.

Default Virtual Server

Software virtual servers work using the HTTP/1.1 Host header. If the end user’s browser does not send the Host header, or if the server cannot find the virtual server specified by the Host header, Sun Java System Web Server handles the request using a default virtual server. Also, for hardware virtual servers, if Sun Java System Web Server cannot find the virtual server corresponding to the IP address, it displays the default virtual server. You can configure the default virtual server to send an error message or serve pages from a special document root.

Tuning

You can specify a default virtual server for an individual listen socket and for the server instance. If a given listen socket does not have a default virtual server, the server instance’s default virtual server is used.

You can specify a default virtual server for a listen socket by:

Keep-Alive/Persistent Connection Information

This section provides information about the server’s HTTP-level keep-alive system. For additional tuning information, see Monitoring Current Activity Using the perfdump Utility

The following example shows the keep-alive statistics displayed by perfdump:

KeepAliveInfo:
--------------------
KeepAliveCount        0/256
KeepAliveHits         0
KeepAliveFlushes      0
KeepAliveRefusals     0
KeepAliveTimeouts     0
KeepAliveTimeout      30 seconds

Note –

The name "keep-alive" should not be confused with TCP "keep-alives." Also, note that the name "keep-alive" was changed to "Persistent Connections" in HTTP/1.1, but the .perf continues to refer to them as "KeepAlive" connections.


Both HTTP/1.0 and HTTP/1.1 support the ability to send multiple requests across a single HTTP session. A web server can receive hundreds of new HTTP requests per second. If every request was allowed to keep the connection open indefinitely, the server could become overloaded with connections. On UNIX/Linux systems this could lead to a file table overflow very easily.

To deal with this problem, the server maintains a "Maximum number of waiting keep-alive connections" counter. A "waiting" keep-alive connection has fully completed processing the previous request, and is now waiting for a new request to arrive on the same connection. If the server has more than the maximum waiting connections open when a new connection waits for a keep-alive request, the server closes the oldest connection. This algorithm keeps an upper bound on the number of open waiting keep-alive connections that the server can maintain.

Sun Java System Web Server does not always honor a keep-alive request from a client. The following conditions cause the server to close a connection, even if the client has requested a keep-alive connection:

KeepAliveThreads

You can configure the number of threads used in the keep-alive system by:

KeepAliveCount

This setting has two numbers:

Tuning

You can tune the maximum number of sessions that the server allows to wait at one time before closing the oldest connection by:


Note –

The number of connections specified by MaxKeepAliveConnections is divided equally among the keep-alive threads. If MaxKeeepAliveConnections is not equally divisible by KeepAliveThreads, the server may allow slightly more than MaxKeepAliveConnections simultaneous keep-alive connections.


KeepAliveHits

The number of times a request was successfully received from a connection that had been kept alive.

This setting is not tunable.

KeepAliveFlushes

The number of times the server had to close a connection because the KeepAliveCount exceeded the MaxKeepAliveConnections. In the current version of the server, the server does not close existing connections when the KeepAliveCount exceeds the MaxKeepAliveConnections. Instead, new keep-alive connections are refused and the KeepAliveResusals count is incremented.

KeepAliveRefusals

The number of times the server could not hand off the connection to a keep-alive thread, possibly due to too many persistent connections (or when KeepAliveCount exceeds MaxKeepAliveConnections). Suggested tuning would be to increase MaxKeepAliveConnections.

KeepAliveTimeout

The time (in seconds) before idle keep-alive connections are closed.

KeepAliveTimeouts

The number of times the server terminated keep-alive connections as the client connections timed out, without any activity. This is a useful statistic to monitor; no specific tuning is advised.

UseNativePoll

This option is not displayed in perfdump or Server Manager statistics. However, for UNIX/Linux users, it should be enabled for maximum performance.

ProcedureTo enable native poll for your keep-alive system from the Server Manager

  1. Go to the Server Manager Preferences tab and select the Mangus Editor.

  2. From the drop-down list, choose Keep-Alive Settings and click Manage.

  3. Use the drop-down list to set UseNativePoll to On.

  4. Click OK, and then click Apply.

  5. Select Apply Changes to restart the server for your changes to take effect.

Session Creation Information

Session creation statistics are only displayed in perfdump. Following is an example of the statistics displayed:

SessionCreationInfo:
------------------------
Active Sessions           1
Total Sessions Created    48/128

Active Sessions shows the number of sessions (request processing threads) currently servicing requests.

Total Sessions Created shows both the number of sessions that have been created and the maximum number of sessions allowed.

Reaching the maximum number of configured threads is not necessarily undesirable, and you do not need to automatically increase the number of threads in the server. Reaching this limit means that the server needed this many threads at peak load, but as long as it was able to serve requests in a timely manner, the server is adequately tuned. However, at this point connections will queue up in the connection queue, potentially overflowing it. If you check your perfdump output on a regular basis and notice that total sessions created is often near the RqThrottle maximum, you should consider increasing your thread limits.

Tuning

You can increase your thread limits by:

Cache Information

The cache information section provides statistics on how your file cache is being used. The file cache caches static content so that the server handles requests for static content quickly. For tuning information, seeTuning the File Cache.

Following is an example of how the cache statistics are displayed in perfdump:

CacheInfo:
------------------
enabled             yes
CacheEntries        0/1024
Hit Ratio           0/0 (  0.00%)
Maximum Age         30

enabled

If the cache is disabled, the rest of this section is not displayed.

Tuning

The cache is enabled by default. You can disable it by:

CacheEntries

The number of current cache entries and the maximum number of cache entries are both displayed. A single cache entry represents a single URI.

Tuning

You can set the maximum number of cached entries by:

Hit Ratio (CacheHits / CacheLookups)

The hit ratio gives you the number of file cache hits versus cache lookups. Numbers approaching 100% indicate the file cache is operating effectively, while numbers approaching 0% could indicate that the file cache is not serving many requests.

This setting is not tunable.

Maximum Age

This displays the maximum age of a valid cache entry. The parameter controls how long cached information is used after a file has been cached. An entry older than the maximum age is replaced by a new entry for the same file.

Tuning

If your web site’s content changes infrequently, you may want to increase this value for improved performance. You can set the maximum age by:

Thread Pools

Three types of thread pools can be configured through the Server Manager:

Thread Pools (UNIX/Linux Only)

Since threads on UNIX/Linux are always operating system (OS)-scheduled, as opposed to user-scheduled, UNIX/Linux users do not need to use native thread pools, and this option is not offered in the user interface for these platforms. However, you can edit the OS-scheduled thread pools and add new thread pools if needed, using the Server Manager.

Native Thread Pools (Windows Only)

On Windows, the native thread pool (NativePool) is used internally by the server to execute NSAPI functions that require a native thread for execution. Windows users can edit native thread pool settings using the Server Manager.

Sun Java System Web Server uses NSPR, which is an underlying portability layer providing access to the host OS services. This layer provides abstractions for threads that are not always the same as those for the OS-provided threads. These non-native threads have lower scheduling overhead so their use improves performance. However, these threads are sensitive to blocking calls to the OS, such as I/O calls. To make it easier to write NSAPI extensions that can make use of blocking calls, the server keeps a pool of threads that safely support blocking calls. This usually means it is a native OS thread. During request processing, any NSAPI function that is not marked as being safe for execution on a non-native thread is scheduled for execution on one of the threads in the native thread pool.

If you have written your own NSAPI plugins such as NameTrans, Service, or PathCheck functions, these execute by default on a thread from the native thread pool. If your plugin makes use of the NSAPI functions for I/O exclusively or does not use the NSAPI I/O functions at all, then it can execute on a non-native thread. For this to happen, the function must be loaded with a NativeThread=”no” option, indicating that it does not require a native thread.

To do this, add the following to the "load-modules" Init line in the magnus.conf file:

Init funcs="pcheck_uri_clean_fixed_init"
shlib="C:/Netscape/p186244/P186244.dll" fn="load-modules" 
NativeThread="no"

The NativeThread flag affects all functions in the funcs list, so if you have more than one function in a library, but only some of them use native threads, use separate Init lines.

Generic Thread Pools (Windows Only)

On Windows, you can set up additional thread pools using the Server Manger. Use thread pools to put a limit on the maximum number of requests answered by a service function at any moment. Additional thread pools are a way to run thread-unsafe plugins. By defining a pool with a maximum number of threads set to 1, only one request is allowed into the specified service function.

Idle /Peak /Limit

Idle indicates the number of threads that are currently idle. Peak indicates the peak number in the pool. Limit indicates the maximum number of native threads allowed in the thread pool, and is determined by the setting of NativePoolMaxThreads.

Tuning

You can modify the NativePoolMaxThreads by:

Work Queue Length /Peak /Limit

These numbers refer to a queue of server requests that are waiting for the use of a native thread from the pool. The Work Queue Length is the current number of requests waiting for a native thread.

Peak is the highest number of requests that were ever queued up simultaneously for the use of a native thread since the server was started. This value can be viewed as the maximum concurrency for requests requiring a native thread.

Limit is the maximum number of requests that can be queued at one time to wait for a native thread, and is determined by the setting of NativePoolQueueSize.

Tuning

You can modify the NativePoolQueueSize by:

NativePoolStackSize

The NativePoolStackSize determines the stack size in bytes of each thread in the native (kernel) thread pool.

Tuning

You can modify the NativePoolStackSize by:

NativePoolQueueSize

The NativePoolQueueSize determines the number of threads that can wait in the queue for the thread pool. If all threads in the pool are busy, then the next request-handling thread that needs to use a thread in the native pool must wait in the queue. If the queue is full, the next request-handling thread that tries to get in the queue is rejected, with the result that it returns a busy response to the client. It is then free to handle another incoming request instead of being tied up waiting in the queue.

Setting the NativePoolQueueSize lower than the RqThrottle value causes the server to execute a busy function instead of the intended NSAPI function whenever the number of requests waiting for service by pool threads exceeds this value. The default returns a "503 Service Unavailable" response and logs a message if LogVerbose is enabled. Setting the NativePoolQueueSize higher than RqThrottle causes the server to reject connections before a busy function can execute.

This value represents the maximum number of concurrent requests for service that require a native thread. If your system is unable to fulfill requests due to load, letting more requests queue up increases the latency for requests, and could result in all available request threads waiting for a native thread. In general, set this value to be high enough to avoid rejecting requests by anticipating the maximum number of concurrent users who would execute requests requiring a native thread.

The difference between this value and RqThrottle is the number of requests reserved for non-native thread requests, such as static HTML and image files. Keeping a reserve and rejecting requests ensures that your server continues to fill requests for static files, which prevents it from becoming unresponsive during periods of very heavy dynamic content load. If your server consistently rejects connections, this value is either set too low, or your server hardware is overloaded.

Tuning

You can modify the NativePoolQueueSize by:

NativePoolMaxThreads

NativePoolMaxThreads determine the maximum number of threads in the native (kernel) thread pool.

A higher value allows more requests to execute concurrently, but has more overhead due to context switching, so bigger is not always better. Typically, you will not need to increase this number, but if you are not saturating your CPU and you are seeing requests queue up, then you should increase this number.

Tuning

You can modify the NativePoolMaxThreads by:

NativePoolMinThreads

Determines the minimum number of threads in the native (kernel) thread pool.

Tuning

You can modify the NativePoolMinThreads by:

DNS Cache Information

The DNS cache caches IP addresses and DNS names. Your server’s DNS cache is disabled by default. Statistics are displayed in the DNS Statistics for Process ID page under Monitor in the Server Manager.

enabled

If the DNS cache is disabled, the rest of this section is not displayed.

Tuning

By default, the DNS cache is off. You can enable DNS caching by:

CacheEntries (CurrentCacheEntries / MaxCacheEntries)

The number of current cache entries and the maximum number of cache entries. A single cache entry represents a single IP address or DNS name lookup. The cache should be as large as the maximum number of clients that will access your web site concurrently. Note that setting the cache size too high will waste memory and degrade performance.

Tuning

You can set the maximum size of the DNS cache by:

HitRatio (CacheHits / CacheLookups)

The hit ratio displays the number of cache hits versus the number of cache lookups.

This setting is not tunable.

Busy Functions

The default busy function returns a "503 Service Unavailable" response and logs a message if LogVerbose is enabled. You may wish to modify this behavior for your application. You can specify your own busy functions for any NSAPI function in the obj.conf file by including a service function in the configuration file in this format:

busy="<my-busy-function>"

For example, you could use this sample service function:

Service fn="send-cgi" busy="service-toobusy"

This allows different responses if the server become too busy in the course of processing a request that includes a number of types (such as Service, AddLog, and PathCheck). Note that your busy function will apply to all functions that require a native thread to execute when the default thread type is non-native.

To use your own busy function instead of the default busy function for the entire server, you can write an NSAPI init function that includes a func_insert call as shown below:

extern "C" NSAPI_PUBLIC int my_custom_busy_function(pblock *pb, 
Session *sn, Request *rq);
my_init(pblock *pb, Session *, Request *){
func_insert("service-toobusy", my_custom_busy_function);
}

Busy functions are never executed on a pool thread, so you must be careful to avoid using function calls that could cause the thread to block.