The configuration examples and recommended settings described in this chapter are for illustrative purposes only. Consult your own use case scenarios to determine which configuration options can provide performance improvements.

5.1 About Oracle HTTP Server

Oracle HTTP Server (OHS) is the Web server component for Oracle Fusion Middleware. It provides a listener for Oracle WebLogic Server and the framework for hosting static pages, dynamic pages, and applications over the Web. Oracle HTTP Server is based on the Apache 2.2.x infrastructure, and includes modules developed specifically by Oracle. The features of single sign-on, clustered deployment, and high availability enhance the operation of the Oracle HTTP Server.

For more information on the Apache open-source software infrastructure, see the Apache Software Foundation web site at http://www.apache.org/.

5.2 Tuning Considerations for Oracle HTTP Server Directives

Oracle HTTP Server uses directives in httpd.conf. This configuration file specifies the maximum number of HTTP requests that can be processed simultaneously, logging details, and certain limits and time outs.

Worker - This uses Multi-Process-Multi-Threads model and is the default MPM on all platforms other than Microsoft Windows platforms. Multi-thread support makes it more scalable by using fewer system resources and multi-process support makes it more stable.

WinNT - This MPM is for Windows platforms only. It consists of a parent process and a child process. The parent process is the control process, and the child process creates threads to handle requests.

Prefork - This is Apache 1.3.x style and uses processes instead of threads. This is considered the least efficient MPM.

The directives for each MPM type are defined in the ORACLE_INSTANCE/config/OHSComponent/<ohsname>/httpd.conf file. The default MPM type is Worker MPM. To use a different MPM (such as Prefork MPM), edit the ORACLE_HOME/ohs/bin/apachectl file.

Note:

The information in this chapter is based on the use of Worker and WinNT MPMs, which use threads. The directives listed below may not be applicable if you are using the prefork MPM. If you are using Oracle HTTP Server based on Apache 1.3.x or Apache 2.2 with prefork MPM, refer to the Oracle Application Server 10g Release 3 documentation at http://www.oracle.com/technology/documentation/appserver10132.html.

Table 5-1 Oracle HTTP Server Configuration Properties

Directive

Description

ListenBackLog

This directive maps to the Maximum Queue Length field on the Performance Directives screen.

Specifies the maximum length of the queue of pending connections. Generally no tuning is needed. Note that some operating systems do not use exactly what is specified as the backlog, but use a number based on, but normally larger than, what is set.

Default Value: 511

MaxClients

This directive maps to the Maximum Requests field on the Performance Directives screen.

Note that this parameter is not available in mod_winnt (Microsoft Windows). Winnt uses a single process, multi-threaded model and is controlled by ThreadLimit directive.

Specifies a limit on the total number of servers running, that is, a limit on the number of clients who can simultaneously connect. If the number of client connections reaches this limit, then subsequent requests are queued in the TCP/IP system up to the limit specified with the ListenBackLog directive (after the queue of pending connections is full, new requests generate connection errors until a thread becomes available).

You can configure the MaxClients directive in the httpd.conf file up to a maximum of 8000 (8K) (the default value is 150). If your system is not resource-saturated and you have a user population of more than 150 concurrent HTTP/Thread connections, you can improve your performance by increasing MaxClients to increase server concurrency. Increase MaxClients until your system becomes fully utilized (85% is a good threshold).

Conversely, when system resources are saturated, increasing MaxClients does not improve performance. In this case, the MaxClients value could be reduced as a throttle on the number of concurrent requests on the server.

If the server handles persistent connections, then it may require sufficient concurrent httpd or thread server processes to handle both active and idle connections. When you specify MaxClients to act as a throttle for system concurrency, you must consider that persistent idle httpd connections also consume httpd/thread processes. Specifically, the number of connections includes the currently active persistent and non-persistent connections and the idle persistent connections. A persistent, KeepAlive, http connection consumes an httpd child process, or thread, for the duration of the connection, even if no requests are currently being processed for the connection.

If you have sufficient capacity, KeepAlive should be enabled; using persistent connections improves performance and prevents wasting CPU resources reestablishing HTTP connections. Normally, you should not change KeepAlive parameters.

The maximum allowed value for MaxClients is 8192 (8K).

Default Value: 150

StartServers

This directive maps to the Initial Child Server Processes field on the Performance Directives screen.

Specifies the number of child server processes created on startup. If you expect a sudden load after restart, set this value based on the number child servers required.

Note that the following parameters are inter-related and applicable only on UNIX platforms (worker_mpm):

MaxClients

MaxSpareThreads and MinSpareThreads

ServerLimit and StartServers

On the Windows platform (mpm_winnt), as well as UNIX platforms, the following parameters are important to tune:

ThreadLimit

ThreadsPerChild

Note that each child process has a set of child threads defined for them and that can actually handle the requests. Use ThreadsPerChild in connection with this directive.

The values of ThreadLimit, ServerLimit, and MaxClients can indirectly affect this value. Read the notes for these directives and use them in conjunction with this directive.

Default Value: 2

ServerLimit

Note that this parameter is not available in mod_winnt (Microsoft Windows). Winnt uses a single process, multi-threaded model

Specifies an upper limit on the number of server (child) processes that can exist or be created. This value overrides the StartServers value if that value is greater than the ServerLimit value. This is used to control the maximum number of server processes that can be created.

Default Value: 16

ThreadLimit

Specifies the upper limit on the number of threads that can be created under a server (child) process. This value overrides the ThreadsPerChild value if that value is greater than the ThreadLimit value. This is used to control the maximum number of threads created per process to avoid conflicts/issues.

Default Values:

Windows Multi-Processing Module (mpm_winnt): 1920

All others: 64

ThreadsPerChild

This directive maps to the Threads Per Child Server Process field on the Performance Directives screen.

Sets the number of threads created by each server (child) process at startup.

Default Value: 64 when mpm_winnt is used and 25 when Worker MPM is used.

The ThreadsPerChild directive works with other directives, as follows:

At startup, Oracle HTTP Server creates a parent process, which creates several child (server) processes as defined by the StartServers directive. Each server process creates several threads (server/worker), as specified in ThreadsPerChild, and a listener thread which listens for requests and transfers the control to the worker/server threads.

After startup, based on load conditions, the number of server processes and server threads (children of server processes) in the system are controlled by MinSpareThreads (minimum number of idle threads in the system) and MaxSpareThreads (maximum number of idle threads in the system). If the number of idle threads in the system is more than MaxSpareThreads, Oracle HTTP Server terminates the threads and processes if there are no child threads for a process. If the number of idle threads is fewer than MinSpareThreads, it creates new threads and processes if the ThreadsPerChild value has already been reached in the running processes.

The following directives control the limit on the above directives. Note that the directives below should be defined before the directives above for them to take effect.

ServerLimit - Defines the upper limit on the number of servers that can be created. This affects MaxClients and StartServers.

ThreadLimit - Defines the upper limit on ThreadsPerChild. If ThreadsPerChild is greater than ThreadLimit, then it is automatically trimmed to the latter value.

MaxClients - Defines the upper limit on the number of server threads that can process requests simultaneously. This should be equal to the number of simultaneous connections that can be made. This value should be a multiple of ThreadsPerChild. If MaxClients is greater than ServerLimit multiplied by ThreadsPerChild, it is automatically be trimmed to the latter value.

MaxRequestsPerChild

This directive maps to the Max Requests Per Child Server Process field on the Performance Directives screen.

Specifies the number of requests each child process is allowed to process before the child process dies. The child process ends to avoid problems after prolonged use when Apache (and any other libraries it uses) leak memory or other resources. On most systems, this is not needed, but some UNIX systems have notable leaks in the libraries. For these platforms, set MaxRequestsPerChild to 10000; a setting of 0 means unlimited requests.

This value does not include KeepAlive requests after the initial request per connection. For example, if a child process handles an initial request and 10 subsequent "keep alive" requests, it would only count as 1 request toward this limit.

Default Value: 0

Note: On Windows systems MaxRequestsPerChild should always be set to 0 (unlimited) since there is only one server process.

MaxSpareThreads

MinSpareThreads

These directives map to the Maximum Idle Threads and Minimum Idle Threads fields on the Performance Directives screen.

Note that these parameters are not available in mod_winnt (Windows platform).

Controls the server-pool size. Rather than estimating how many server threads you need, Oracle HTTP Server dynamically adapts to the actual load. The server tries to maintain enough server threads to handle the current load, plus a few additional server threads to handle transient load increases such as multiple simultaneous requests from a single browser.

The server does this by periodically checking how many server threads are waiting for a request. If there are fewer than MinSpareThreads, it creates a new spare. If there are more than MaxSpareThreads, some of the spares are removed.

Default Values:

MaxSpareThreads: 75

MinSpareThreads: 25

Timeout

This directive maps to the Request Timeout field on the Performance Directives screen.

The number of seconds before incoming receives and outgoing sends time out.

Default Value: 300

KeepAlive

This directive maps to the Multiple Requests Per Connection field on the Performance Directives screen.

Whether or not to allow persistent connections (more than one request per connection). Set to Off to deactivate.

Default Value: On

MaxKeepAliveRequests

The maximum number of requests to allow during a persistent connection. Set to 0 to allow an unlimited amount.

If you have long client sessions, consider increasing this value.

Default Value: 100

KeepAliveTimeout

This directive maps to the Allow With Connection Timeout (seconds) field, which is located under the Multiple Requests Per Connection field, on the Performance Directives screen.

Number of seconds to wait for the next request from the same client on the same connection.

Default Value: 5 seconds

limit

ulimit

Number of objects that a program uses to read or write to an open file or open network sockets. A lack of available file descriptors can impact operating system performance.

Tuning the file descriptor limit can be accomplished by configuring the hard limit (ulimit) in a shell script which starts the OHS. Once the hard limit has been set the OHS will then adjust the soft limit (limit) to match.

Note that configuring file descriptor limits is platform specific. Refer to your operating system documentation for more information.

5.2.1 Reducing Httpd Process Availability with Persistent Connections

If your browser supports persistent connections, you can support them on the server using the KeepAlive directives in the Oracle HTTP Server. Persistent Connections can improve performance by reducing the work load on the server. With Persistent Connections enabled, the server does not have to repeat the work to set up the connections with a client.

The default settings for the KeepAlive directives are:

KeepAlive on
MaxKeepAliveRequests 100
KeepAliveTimeOut 5

These settings allow enough requests per connection and time between requests to reap the benefits of the persistent connections, while minimizing the drawbacks. You should consider the size and behavior of your own user population when setting these values. For example, if you have a large user population and the users make small infrequent requests, you may want to reduce the keepAlive directive default settings, or even set KeepAlive to off. If you have a small population of users that return to your site frequently, you may want to increase the settings.

KeepAlive option should be used judiciously along with MaxClients directive. KeepAlive option would tie a worker thread to an established connection until it times out or the number of requests reaches the limit specified by MaxKeepAliveRequests. This means that the connections or users in the ListenBacklog queue would be starving for a worker until the worker is relinquished by the keep-alive user. The starvation for resources happens on the KeepAlive user load with user population consistently higher than that specified in the MaxClients.

Note:

The Maxclients property is applicable only to UNIX platforms. On Windows, the same functionality is achieved through the ThreadLimit and ThreadsPerChild parameters.

Increasing MaxClients may impact performance in the following ways:

A high number of MaxClients can overload the system resources and may lead to poor performance.

For a high user population with fewer requests, consider increasing the MaxClients to support KeepAlive connections to avoid starvation. Note that this can impact overall performance if the user concurrency increases. System performance is impacted by increased concurrency and can possibly cause the system to fail.

MaxClients should always be set to a value where the system would be stable or performing optimally (~85% CPU).

Typically for high user population with less frequent requests, consider turning the KeepAlive option off or reduce it to a very low value to avoid starvation.

Disabling the KeepAlive connection may impact performance in the following ways:

Connection establishment for every request has a cost.

If the frequency of creating and closing connections is higher, then some system resources are used. The TCP connection has a time_wait interval before it can close the socket connection and open file descriptors for every connection. The default time_wait value is 60 seconds and each connection can take 60 seconds to close, even after it is relinquished by the server.

WARNING:

To avoid potential performance issues, values for any parameters should be set only after considering the nature of the workload and the system capacity.

5.3 Logging Options for Oracle HTTP Server

This section discusses types of logging, log levels, and the performance implications for using logging.

5.3.1 Access Logging

Access logs are generally enabled to track who accessed what. The access_log file, available in the ORACLE_INSTANCE/diagnostics/logs/OHS/ohsname directory, contains an entry for each request that is processed. This file grows as time passes and can consume disk space. Depending on the nature of the workload, the access_log has little impact on performance. If you notice that performance is becoming an issue, the file can be disabled if some other proxy or load balancer is used and gives the same information.

5.3.2 Configuring the HostNameLookups Directive

By default, the HostNameLookups directive is set to Off. The server writes the IP addresses of incoming requests to the log files. When HostNameLookups is set to On, the server queries the DNS system on the Internet to find the host name associated with the IP address of each request, then writes the host names to the log. Depending on the server load and the network connectivity to your DNS server, the performance impact of the DNS HostNameLookup may be high. When possible, consider logging only IP addresses. On UNIX systems, you can resolve IP addresses to host names off-line, with the logresolve utility found in the ORACLE_HOME/Apache/Apache/bin/ directory.

5.3.3 Error logging

The server notes unusual activity in an error log. The ohsname.log file, available in ORACLE_INSTANCE/diagnostics/logs/OHS/ohsname directory, contains errors, warnings, system information, and notifications (depending on the log-level setting).

The httpd.conf file contains the error log configuration for OHS. The logging mode is defined by the "OraLogMode" directive. The default is "odl-text", which produces the Oracle diagnostic logging format in a text file. Alternatively, change this to "odl-xml" to produce the Oracle diagnostic logging format in an XML file.

For Oracle diagnostic-style logging, "OraLogSeverity" directive is used for setting the log level.

For Apache-style logging, the ErrorLog and LogLevel directives identify the log file and the level of detail of the messages recorded. The default debug level is Warn.

Excessive logging can have some performance cost and may also fill disk space. The log level control should be used based on need. For requests that use dynamic resources, for example, requests that use mod_osso or mod_plsql, there is a performance cost associated with setting higher debugging levels, such as the debug level.

Secure Sockets Layer (SSL) is a protocol developed by Netscape Communications Corporation that provides authentication and encrypted communication over the Internet. Conceptually, SSL resides between the application layer and the transport layer on the protocol stack. While SSL is technically an application-independent protocol, it has become a standard for providing security over HTTP, and all major web browsers support SSL.

SSL can become a bottleneck in both the responsiveness and the scalability of a web-based application. Where SSL is required, the performance challenges of the protocol should be carefully considered. Session management, in particular session creation and initialization, is generally the most costly part of using the SSL protocol, in terms of performance.

This section covers the following SSL performance-related information:

5.4.1.1 Caching SSL on Oracle HTTP Server

When an SSL connection is initialized, a session-based handshake between client and server occurs that involves the negotiation of a cipher suite, the exchange of a private key for data encryption, and server and, optionally, client, authentication through digitally-signed certificates.

After the SSL session state has been initiated between a client and a server, the server can avoid the session creation handshake in subsequent SSL requests by saving and reusing the session state. The Oracle HTTP Server caches a client's SSL session information by default. With session caching, only the first connection to the server incurs high latency.

The SSLSessionCacheTimeout directive in ssl.conf determines how long the server keeps a saved SSL session (the default is 300 seconds). Session state is discarded if it is not used after the specified time period, and any subsequent SSL request must establish a new SSL session and begin the handshake again. The SSLSessionCache directive specifies the location for saved SSL session information (the default location is the following directory):

Saving SSL session state can significantly improve performance for applications using SSL. For example, in a simple test to connect and disconnect to an SSL-enabled server, the elapsed time for 5 connections was 11.4 seconds without SSL session caching. With SSL session caching enabled, the elapsed time for 5 round trips was 1.9 seconds.

The reuse of saved SSL session state has some performance costs. When SSL session state is stored to disk, reuse of the saved state normally requires locating and retrieving the relevant state from disk. This cost can be reduced when using HTTP persistent connections. Oracle HTTP Server uses persistent HTTP connections by default, assuming they are supported on the client side. In HTTP over SSL as implemented by Oracle HTTP Server, SSL session state is kept in memory while the associated HTTP connection is persisted, a process which essentially eliminates the performance impacts associated with SSL session reuse (conceptually, the SSL connection is kept open along with the HTTP connection). For more information see Section 5.2.1, "Reducing Httpd Process Availability with Persistent Connections".

5.4.1.2 Using SSL Application Level Data Encryption

In most applications using SSL, the data encryption cost is small compared with the cost of SSL session management. Encryption costs can be significant where the volume of encrypted data is large, and in such cases the data encryption algorithm and key size chosen for an SSL session can be significant. In general there is a trade-off between security level and performance.

Oracle HTTP Server negotiates a cipher suite with a client based on the SSLCipherSuite attribute specified in ssl.conf. OHS 11g uses 128 bit Encryption algorithm by default and no longer supports lower encryption. Note that the previous release [10.1.3x] used 64 bit encryption for Windows. For UNIX, the 10.x releases had 128 bit encryption used by default.

5.4.1.3 Tuning Considerations for SSL Performance

The following recommendations can assist you with determining performance requirements when working with Oracle HTTP Server and SSL.

The SSL handshake is an inherently resource intensive process in terms of both CPU usage and response time. Thus, use SSL only where needed. Determine the parts of the application that require the security, and the level of security required, and protect only those parts at the requisite security level. Attempt to minimize the need for the SSL handshake by using SSL sparingly, and by reusing session state as much as possible. For example, if a page contains a small amount of sensitive data and several non-sensitive graphic images, use SSL to transfer the sensitive data only, use normal HTTP to transfer the images. If the application requires server authentication only, do not use client authentication. If the performance goals of an application cannot be met by this method alone, additional hardware may be required.

Design the application to use SSL efficiently. Group secure operations to take advantage of SSL session reuse and SSL connection reuse.

Use persistent connections, if possible, to minimize cost of SSL session reuse.

Tune the session cache timeout value (the SSLSessionCacheTimeout directive in ssl.conf). A trade-off exists between the cost of maintaining an SSL session cache and the cost of establishing a new SSL session. As a rule, any secured business process, or conceptual grouping of SSL exchanges, should be completed without incurring session creation more than once. The default value for the SSLSessionCacheTimeout attribute is 300 seconds. It is a good idea to test an application's usability to help tune this setting.

If large volumes of data are being protected through SSL, pay close attention to the cipher suite being used. The SSLCipherSuite directive specified in ssl.conf controls the cipher suite. If lower levels of security are acceptable, use a less-secure protocol using a smaller key size (this may improve performance significantly). Finally, test the application using each available cipher suite for the specified security level to find the optimal suite.

If SSL remains a bottleneck to the performance and scalability of your application, after taking the preceding considerations into account, consider deploying multiple Oracle HTTP Server instances over a hardware cluster or consider the use of SSL accelerator cards.

5.4.2 Oracle HTTP Server Port Tunneling Performance Issues

When OracleAS Port Tunneling is configured, every request processed passes through the OracleAS Port Tunneling infrastructure. Thus, using OracleAS Port Tunneling can have an impact on the overall Oracle HTTP Server request handling performance and scalability.

With the exception of the number of OracleAS Port Tunneling processes to run, the performance of OracleAS Port Tunneling is self-tuning. The only performance control available is to start more OracleAS Port Tunneling processes; this increases the number of available connections and the scalability of the system.

The number of OracleAS Port Tunneling processes is based on the degree of availability required, and the number of anticipated connections. This number cannot be automatically determined because for each additional process a new port must be opened through the firewall between the DMZ and the intranet. You cannot start more processes than you have open ports, and you do not want less processes than open ports, since in this case ports would not have any process bound to them.

To measure the OracleAS Port Tunneling performance, determine the request time for servlet requests that pass through the OracleAS Port Tunneling infrastructure. The response time running with OracleAS Port Tunneling should be compared with a system without OracleAS Port Tunneling to determine whether your performance requirements can be met using OracleAS Port Tunneling.

5.5.1 Analyzing Static Versus Dynamic Requests

It is important to understand where your server is spending resources so you can focus your tuning efforts in the areas where the most stands to be gained. In configuring your system, it can be useful to know what percentage of the incoming requests are static and what percentage are dynamic.

Generally, you want to concentrate your tuning effort on dynamic pages because dynamic pages can be costly to generate. Also, by monitoring and tuning your application, you may find that much of the dynamically generated content, such as catalog data, can be cached, sparing significant resource usage.

5.5.2 Managing PL/SQL Requests

You can get unrepresentative results when data outliers appear. This can sometimes occur at start-up. To simulate a simple example, assume that you ran a PL/SQL "Hello, World" application for about 30 seconds. Examining the results, you can see that the work was all done in mod_plsql.c:

Note that handle.maxTime is much higher than handle.avg for this module. This is probably because when the first request is received, a database connection must be opened. Later requests can make use of the established connection. In this case, to obtain a better estimate of the average service time for a PL/SQL module, that does not include the database connection open time which causes the handle.maxTime to be very large, recalculate the average as in the following:

(time - maxTime)/(completed -1)

For example:

(24023499 - 859330)/(1230 - 1) = 18847.98

5.5.3 Limiting the Number of Enabled Modules

Oracle HTTP Server, which is now based on Apache 2.2, has a slight change in architecture in the way the requests are handled, compared to the previous release of Oracle HTTP Server, which was based on Apache 1.3.

In the new architecture, Oracle HTTP Server invokes the service function of each module that is loaded (in the order of definition in httpd.conf file) until the request is serviced. This indicates that there is some cost associated with invoking the service function of each module, to know if the service is accepted or declined.

Because of this change in architecture, consider placing the most frequently hit modules above the others in the httpd.conf file.

For the static page requests, which are directly deployed to Oracle HTTP Server and served by the default handler, the request has to go through all the modules before the default handler is invoked. This process can impact performance of the request so consider enabling only the modules that are required by the deployed application. Example, if "mod_plsql" is never used by the deployed application, disable it to maintain performance.

In addition, there are a few modules that register their hooks to do some work during the URL translation phase, which would add to the cost of request processing time. Example: mod_security, when enabled, has a cost of about 10% on CPU Cost per Transaction for the specweb benchmark. Again, enable only those modules that are required by your deployed applications to save CPU time.

5.5.4 Tuning the File Descriptor Limit

A lack of available file descriptors can cause a wide variety of symptoms which are not always easily traced back to the operating system's file descriptor limit. Tuning the file descriptor limit can be accomplished by configuring the operating system's hard limit for the user who starts the OHS. Once configured, the OHS will adjust the soft limit to match the operating system limit.

Configuring file descriptor limits is platform-specific. Refer to your operating system documentation for more information. The following code example shows the command for Linux:

APACHECTL_ULIMIT=ulimit -S -n `ulimit -H -n`

Note that this limit must be reconfigured after applying a patch set.

5.5.5 Monitoring Oracle HTTP Server

Oracle Fusion Middleware automatically and continuously measures run-time performance for Oracle HTTP Server. The performance metrics are automatically enabled; you do not need to set options or perform any extra configuration to collect them. If you encounter a problem, such as an application that is running slowly or is hanging, you can view particular metrics to find out more information about the problem.

In addition to the Fusion Middleware Control, Oracle HTTP Server also has Dynamic Monitoring Service (DMS), which collects metrics for every functional piece. You can review these metrics as needed to understand system behavior at a given point of time. This displays memory, CPU information and the minimum, maximum, and average times for the request processing at every layer in Oracle HTTP Server. The metrics also display details about load level, number of threads, number of active connections, and so on, which can help in tuning the system based on real usage.