Skip Headers
Oracle® HTTP Server Administrator's Guide
10g Release 2 (10.1.2)
B14007-04
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

D Load Balancing Using mod_oc4j

This chapter contains information about mod_oc4j load balancing, including metric-based load balancing. Topics include:

D.1 Load Balancing Policies

This section contains information about load balancing policies that mod_oc4j supports:

D.1.1 Random

mod_oc4j randomly selects an OC4J instance from a list of OC4J instances that are candidates to service a request.

D.1.2 Round Robin

mod_oc4j randomly selects an OC4J instance from an ordered list of OC4J instances that are candidates to service a request. Other OC4J instances are selected from the ordered list in turn, until the initially selected server is selected again. This sequence is repeated. If a particular OC4J instance is stopped or is unavailable, then that instance is skipped (no attempt is made to select it) until it can be brought back in service.

D.1.3 Random with Local Affinity

mod_oc4j randomly selects local OC4J processes to service requests. When no local OC4J processes are available, mod_oc4j randomly selects remote OC4J processes and gives them equal opportunity to be selected.

D.1.4 Round Robin with Local Affinity

mod_oc4j routes all requests to local OC4J processes in a round robin manner. When no local processes are available, mod_oc4j routes requests equally to each OC4J process on different hosts.

D.1.5 Random using Routing Weight

mod_oc4j distributes requests according to the routing weight configured for each host. One OC4J process is selected randomly from the OC4J processes on that host.

D.1.6 Round Robin using Routing Weight

mod_oc4j distributes the total request load to OC4J processes on each host based on the routing weight configured to each host. mod_oc4j selects an OC4J process in round robin manner from the OC4J processes on that host.

D.1.7 Metric Based

mod_oc4j routes requests based on run time metrics from OC4J processes that indicate how much load can be placed on the OC4J process.

D.1.8 Metric Based with Local Affinity

mod_oc4j routes all requests to local OC4J processes based on the run time performance metrics of OC4J processes. When there are no local OC4J processes available, mod_oc4j routes requests to each OC4J process on different hosts as per their performance metrics only.

D.2 Load Balancing Parameters

This section discusses the following load balancing parameters:

D.2.1 Oc4jSelectMethod

Selects an OC4J instance for load balancing.

Category Value
Syntax Oc4jSelectMethod roundrobin | roundrobin:local | roundrobin:weighted | random | random:local | random:weighted | metric | metric:local
Required No
Default If Oc4jSelectMethod is not specified, it defaults to "Oc4jSelectMethod roundrobin".
Example Oc4jSelecctMethod random:local

Oc4jSelecctMethod metric

Usage

This directive is only applicable to the base server for Oracle Application Server 10g Release 2 (10.1.2) and an error will be printed at startup if specified within a VirtualHost container.

D.2.2 Oc4jRoutingWeight

Associates a request routing weight for each machine during load balancing. Weighted routing is a load balancing strategy that distributes requests according to a predefined value assigned to each machine based on the predicted ability to handle load.

Category Value
Syntax Oc4jRoutingWeight <node_name> <routing_weight>
Required No
Default It defaults to OC4J processes on all the nodes with routing weight as 1. If Oc4jRoutingWeight is specified, but some hosts are not specified, it defaults to OC4J processes on any non-specified node with routing weight as 1.
Example
  • There are two hosts in an Oracle Application Server cluster: Host_A and Host_B. Each has Oracle HTTP Server and OC4J processes running on them.
    Oc4jSelectMethod random:local 
    Oc4jRoutingWeight Host_A 3 
    Oc4jRoutingWeight Host_B 2 
    

    Oc4jRoutingWeight directives are ignored. mod_oc4j on Host_A randomly routes all requests to OC4J processes on Host_A, mod_oc4j on Host_B randomly routes all requests to OC4J processes on Host_B.

  • There are four hosts in an Oracle Application Server cluster: Host_A, Host_B, Host_C, and Host_D. Each has Oracle HTTP Server and OC4J processes running on them.

    Oc4jSelectMethod roundrobin:weighted 
    Oc4jRoutingWeight Host_A 3 
    Oc4jRoutingWeight Host_B 2 
    

    mod_oc4j on all the machines route three times the number of requests to OC4J processes running on Host_A, two times the number of requests on Host_B, one time the number of requests on Host_C, and one time the number of requests on Host_D in a round robin manner.

  • There are four hosts in an Oracle Application Server cluster: Host_A, Host_B, Host_C, and Host_D. Each has Oracle HTTP Server and OC4J processes running on them.

    Oc4jSelectMethod roundrobin:weighted 
    

    mod_oc4j on all the machines route requests equally to OC4J processes on Host_A, Host_B, Host_C, and Host_D in a round robin manner.

Usage Oc4jRoutingWeight is taken into account only when Oc4jSelectMethod specifies weighted.

"Oc4jRoutingWeight <node_name> <routing_weight>" associates a request routing weight to each node. node_name can be in host name or IP address format. For hosts with multiple interfaces, if different interfaces are specified, it is assumed that they are different hosts.


This directive is only applicable to the base server for Oracle Application Server 10g Release 2 (10.1.2) and an error will be printed at startup if specified within a VirtualHost container.

D.3 Metric-based Load Balancing

Metric-based load balancing is a way to distribute request load among OC4Js based on a "health" metric that each OC4J reports. The metric range is between 0 and 100, where 0 is very busy, or unhealthy, and 100 is not busy, or healthy. When metric-based load balancing is enabled, requests are distributed among OC4Js based on a ratio of a metric received for an individual OC4J, divided by the total of the metrics received from all the OC4Js.

For example, OC4J process p1 reports a metric of 20, process p2 reports a metric of 40, and process p3 reports a metric of 90. The requests would be distributed as follows:

You must configure Oracle HTTP Server and OC4J to enable metric-based load balancing. The following sections contain the required configuration information:

D.3.1 Configuring Oracle HTTP Server

On the Oracle HTTP Server side, specify "Oc4jSelectMethod metric" or "Oc4jSelectMethod metric:local" in mod_oc4j.conf.

D.3.2 Configuring OC4J

On the OC4J side, you must configure the metric collector in ORACLE_HOME/j2ee/home/config/server.xml in UNIX or ORACLE_HOME/j2ee\home\config\server.xml on Windows. Configuring the <metric-collector> element tells OC4J to start sending a metric to mod_oc4j so that mod_oc4j can make routing decisions to load balance incoming requests to a list of available OC4J instances.

The metric sent from OC4J to mod_oc4j is used only when metric-based load balancing is specified for mod_oc4j and when OC4J runs in an Oracle Application Server environment.

If you specify metric-based load balancing in mod_oc4j and do not specify the <metric-collector> element in server.xml, then mod_oc4j expects OC4J to send metrics, but OC4J does not send metrics. In this case, mod_oc4j reports the following warning message:

No run time metrics for oc4j(opmnid=%s) in notification Oc4jSelectMethod is
configured to use run time metrics, please make sure OC4J side is configured
accordingly. Default to 50.

In this case, mod_oc4j uses the value "50" for each of the OC4J processes and continues.

Likewise, if you specify the <metric-collector> element in server.xml, but do not specify metric-based load balancing in mod_oc4j, then OC4J sends metrics but mod_oc4j is not configured to receive metrics. In this case, mod_oc4j ignores the metrics and uses whatever the configured method is for load balancing. You specify the load balancing method with Oc4jSelectMethod. If no Oc4jSelectMethod is specified, then mod_oc4j uses the default, which is roundrobin.

All OC4Js that are used from this Oracle HTTP Server instance must be configured identically. Otherwise, the number returned from the OC4Js will not be comparable and can produce some very poor load balancing results.

When mod_oc4j receives a notification containing the metrics information from OC4J, it immediately changes the request routing behavior. The default interval between notifications from OC4J is 30 seconds. This value can be configured using the system property opmnPingInterval, which is passed on the command line when OC4J is started by OPMN. To change the interval between notifications, specify the following in opmn.xml under the OC4J <process-set> configuration element:

<module-data> 
  <category id="start-parameters"> 
    <data id="java-options" value="-DopmnPingInterval=<new ping interval value>"/>
  </category> 
</module-data>

Specifying Metrics for OC4J

The following two methods can be used to specify metrics for OC4J:

D.3.2.1 Configuring Metric-based Load Balancing to Use the DMSMetricCollector

In this out of the box method, the <metric-collector> element takes a single attribute: classname. This attribute defines an interface for gathering and calculating a server-wide metric. Use oracle.oc4j.server.DMSMetricCollector for the classname attribute when using a DMS-based metric collector. A DMSMetricCollector instance takes several parameters.

The DMS metric is specified using the 'dms-noun' parameter, which is shown in the configuration example below. This is the metric on which the DMSMetricCollector bases its calculation. The recommended DMS metric for metric-based load balancing is /oc4j/default/WEBS/processRequest.time. This metric represents the processing time of the servlets in the default Web application.

The value sent to OC4J is a weighted average of the value computed based on the current DMS metric value, and the last value computed the last time a value was sent. The default weight is 0.7 for the current value, and 0.3 for the previous value. To modify the weights, one may set the "history-proportion" as shown the following example. This results in a weight of 0.8 for the current value and 0.2 for the previous value.

<metric-collector classname="oracle.oc4j.server.DMSMetricCollector">
   <init-param>
     <param-name>
       dms-noun
     </param-name>
     <param-value>
       /oc4j/default/WEBs/processRequest.time
     </param-value>
   </init-param>
   <init-param>
     <param-name>
       history-proportion
     </param-name>
     <param-value>
       0.2
     </param-value>
   </init-param>
   <init-param>
     <param-name>
       debug
     </param-name>
     <param-value>
       false
     </param-value>
   </init-param>
</metric-collector>


See Also:

Oracle Application Server Performance Guide for a list of DMS metrics.

D.3.2.1.1 How DMS Metrics are Converted for Metric-based Load Balancing

When getMetrics() is called, the value of the DMS metric specified by the dms-noun parameter is obtained. The delta with the previous measurement is computed.

Since the scale is from 0 to 100, and the measurement is potentially unbounded, the following formula is applied:

metric = 100 / (1 + (log (1 + delta)))

As outlined above, this metric should match the current situation, but also reflect on previous metric history. You can assign a weight of 1/3 to the previous history and 2/3 for the average just collected in order to form the new metric.

This new metric becomes the next metric's history, and factors in less and less as time passes. As shown in the configuration example, you can specify the proportion of the previous metric that enters in new metrics, by setting the history-proportion parameter to a floating point value between 0.0 and 1.0. Higher values mean that historical values matter more, making the metric less volatile. A lower value makes the metric reflect the most recent metric. The metric returned is as follows:

smoothedmetric = ((1 - history-proportion) * metric) + (history-proportion * previousmetric)

The smoothedmetric is what is sent to mod_oc4j for load balancing purposes.

D.3.2.2 Building Your Own Metric Collector

You can implement the interface oracle.oc4j.api.MetricCollector to supply your own metric collector to mod_oc4j. The metric has to be between 0 and 100.

All metric collectors must implement the interface oracle.oc4j.api.MetricCollector. The concrete metric collector must have a constructor with no parameters so it can be instantiated.

The schema elements for the feature are in server.xml, and look like:

<metric-collector classname="my.package.name.MyClassName">
  <init-param>
    <param-name>
      mysetting
    </param-name>
    <param-value>
      12345
    </param-value>
  </init-param>
</metric-collector>

As per the preceding example, 0 or more parameters can be set on the metric collector, and are passed to it when setParameters() method is called. setEnabled(true) is called once after setParameters(). It signals the metric collector that it can begin gathering data as needed.


Note:

If the custom metric collector starts threads, the threads need to be daemon threads. Otherwise they may prevent the server from shutting down in an orderly fashion.

After oracle.oc4j.api.MetricCollector has been implemented, package your metric in a jar file and add it to your library path, using the following, in server.xml:

<library path="<path to>/mymetric.jar"/>

D.3.2.2.1 oracle.oc4j.api.MetricCollector

Here is the oracle.oc4j.api.MetricCollector interface:

package oracle.oc4j.api;
 
 import java.util.Map;
 
 /**
  * Defines an interface for gathering and obtaining a server-wide metric.
  * The metric is used in iAS mode, by mod_oc4j, to load balance between
  * virtual oc4j instances.
  * The metric value is relative, and should be between 0 and 100, both
  * inclusive.
  * When configured for metric load balancing,
  * Mod_oc4j will route preferably to an oc4j with the greater value.
  * <p>Concrete instances of this class must have a public empty constructor in
  * order to be loaded and instantiated.
  */
 public interface MetricCollector {
   /**
    * Support for debugging: This is a property name to set to true in order
    * to display the metric that is sent from the server
    */
   String OC4J_METRIC_DEBUG_PROPERTY = "oc4j.metric.debug";
 
   /**
    * Debugging flag that depends on @{link #OC4J_METRIC_DEBUG_PROPERTY}
    */
   boolean DEBUG = Boolean.getBoolean( OC4J_METRIC_DEBUG_PROPERTY );
 
   /**
    * Initial metric to return when no measurement has been made (property key)
    */
   String OC4J_INITIAL_METRIC_PROPERTY = "oc4j.metric.initial";
   /**
    * Initial metric to return when no measurement has been made.
    * Default is 50
    */
   int INITIAL_METRIC = Integer.getInteger( OC4J_INITIAL_METRIC_PROPERTY, 50 ).intValue();
 
   /**
    * Enabled flag for the collector.
    * @return true if the collector is collecting data
    */
   boolean isEnabled();
 
   /**
    */
   void setEnabled( boolean enabled);
 
   /**
    * The parameters the metric collector is configured with.
    * This method will be called even when the set of parameters is null.
    * @param params the key/value pairs the metric collector is configured with,
    * or <code>null</code> if none
    */
   void setParameters( Map params );
 
   /**
    * @return a metric between 0 and 100, inclusive. 100 is better, 0 is worse
    */
   int getMetric();
 
 }