For z/OS platformsDistributed: [AIX MacOS Linux Windows]

Configuring routing rules for Liberty dynamic routing

With the routing rules feature of dynamic routing, you can select requests for special routing behavior based on request information.

Before you begin

Enable Dynamic Routing in a collective controller. Complete the steps in Setting up dynamic routing for Liberty collectives.

Tip: To use routing rules to route to multiple collectives, each collective must have a different name. Use the --collectiveName option when you run the collective create command to name a collective. If the collective is already created, you can provide a logical name for the collective with the connectorClusterName property of the <dynamicRouting> XML element. If the connectorClusterName property is specified, the value takes precedence over the collectiveName specified with the --collectiveName option. See Setting up dynamic routing for multiple Liberty collectives.

About this task

By default, dynamic routing balances the request load across all servers that can handle the request. Configure routing rules to override the default behavior so that routing rules can route requests to specific server resources, redirect requests, or reject requests.

Note: All collective controllers in the collective must provide the same set of routing rules through the dynamic routing service. Add an .xml file that contains the routing rules to the configDropins/defaults directory of one of the controllers to ensure that all controllers use the same routing rules. For more information, see Automatically sharing configurations among replicas.

Procedure

  1. Add the <routingRules> element as a child of the <dynamicRouting> element in the controller server.xml file.

    Specify the webServers attribute of the <routingRules> element. Each <routingRules> element can define the applicable set of web servers where the rules are published. When a web server connects to the DynamicRouting service, the service delivers rules to that web server. If you specify no web servers, the service delivers rules to all web servers that connect. If you specify more than one web server, use a comma (,) as the delimiter. Any rules that are specified with a webServers attribute value of * are delivered to all web servers. See the following example:

    <dynamicRouting>
       <routingRules webServers="webserver1,webserver2">
       ...
       </routingRules>
    </dynamicRouting>
    Specify the overrideAffinity attribute of the <routingRules> element. By default, a request that has affinity to a particular server is sent to that server, even if the request matches a routing rule that does not contain the affinity server as a destination. If the overrideAffinity property is set to true, then selecting a destination that is in a matched rule takes precedence over selecting the affinity server. If the affinity server satisfies the matched rule, the affinity server is chosen, even if the affinity server is in a failover set of endpoints. The overrideAffinity property applies to all routing rules and cannot be set for individual rules.
    <dynamicRouting>
       <routingRules webServers="webserver1" 
    overrideAffinity="true">
       ...
       </routingRules>
    </dynamicRouting>
    
  2. Add <routingRule> elements as children of the <routingRules> element.
    1. Specify an order attribute for the routing rule and set it to an integer. The order attribute is required. Rules are evaluated from lowest order to highest. If more than one rule is assigned the same order attribute, the first rule that is found is published and all other rules with the same order attribute are discarded. A good practice is to leave gaps between the order numbers of the rules to provide space for future rules.
    2. Specify a matchExpression attribute for the routing rule. Set it to an expression that can find matching incoming requests. Match expressions combine a set of fixed operands with operators. You can combine sets of operands and operators by using AND and OR operators.
    <dynamicRouting>
       <routingRules webServers="webserver1,webserver2">
          <routingRule order="100" matchExpression="URI LIKE'/myapp%'">
          ...
          </routingRule>
       </routingRules>
    </dynamicRouting>
    Table 1. matchExpression operands. Include an operand in a matchExpression definition.
    Operand Syntax Description
    Client IPV4 clientipv4 The IP address of the client that uses the Internet Protocol version 4 (IPv4) dotted quad address type of n.n.n.n.
    Client IPV6 clientipv6 The Internet Protocol version 6 (IPv6) 128-bit address type of x:x:x:x:x:x:x:x that follows Request for Comments 1924 (RFC 1924) of the client computer.
    Cookie name cookie$name A cookie name.

    For example, the expression cookie$My_Cookie_Name='My_Cookie_Value' tests a request to see whether it contains a cookie that is named My_Cookie_Name with a My_Cookie_Value value. To test for the presence or absence of a particular cookie, use one of the following expressions:

    cookie$MyCookieName IS NOT NULL 
    cookie$MyCookieName IS NULL
    Header name header$name A header name and value.

    For example, the expression header$Host='localhost' tests a request to see whether it contains an HTTP host header with a locahost value. To test for presence or absence of the host header, use one of the following expressions:

    header$Host IS NOT NULL 
    header$Host IS NULL
    Percentage percentage$val The percentage operand evaluates to true some percentage of the time.

    For example, percentage$50 evaluates to true on average 50% of the time.

    Query parameter queryparm$name A query parameter name and value.

    For example, the expression queryparm$timezone='EST' tests a request to see whether the request contains an HTTP query parameter that is named timezone with an EST value. To test for the presence or absence of a query parameter, use one of the following forms:

    queryparm$timezone IS NOT NULL
    queryparm$timezone IS NULL
    URI uri Uniform Resource Identifier
    Virtual host virtualhost Virtual host target of the request
    Virtual port numeric Virtual port target of the request
    Table 2. matchExpression operators. Include an operator in a matchExpression definition as needed.
    Operator Syntax Description
    Equals = The equality operator expresses a case-sensitive match.
    Equals ignore case EQUALSIGNORECASE Identical to 'String = String' except that the case of the strings is ignored. For example, 'ABC' EQUALSIGNORECASE 'abc' evaluates to true and ('ABC' = 'abc') evaluates to false.
    IN IN Expresses an operand with multiple values in a single expression. For example, for an operand that is called port, to express that the port value can be any or all of the integers 9080, 9090, and 9091, the expression fragment is port IN (9080,9090,9091).

    How the values inside the parentheses are expressed depends on the data type. For example, if port is an integer, the correct syntax is the value without quotation marks. If port is a string, the correct syntax is port IN ('9080','9090','9091').

    Is not null IS NOT NULL Evaluates to true if the specified operand exists.
    Is null IS NULL Evaluates to true if the specified operand does not exist.
    Like LIKE Expresses pattern matching for string operand values. The value must contain the wildcard character percent sign (%) in the position where the pattern matching starts. For example:
    • The host LIKE %blanca expression matches the word blanca or any other word that ends in blanca.
    • The host LIKE blanca% expression matches the word blanca or any other word that starts with blanca.
    • The host LIKE %blanca% expression matches the word blanca or any word that contains blanca.
    Like ignore case LIKEIGNORECASE Identical to 'string LIKE string' except that the case of the strings is ignored.
    Like in LIKEIN Evaluates whether a string exists in a list of strings. For example, string likein (string1%, string2%, string3%, etc.) evaluates to true if string matches one or more of the strings in the parentheses. In this example, the parentheses contain three string values.
  3. Specify an action type for a routing rule.

    The three possible action types are permitAction, redirectAction, or rejectAction. Specify only one of the three action types for each routing rule.

    • Specify the permitAction action type to route requests to identified endpoints.
      1. Add the <permitAction> element to a <routingRule> element.
      2. Optionally, add the allowMaintenanceModeServers attribute to the <permitAction> element to specify whether requests that match the rules are sent to servers in maintenance mode. The default value for this attribute is false. When this attribute is set to true, requests that match this rule can be sent to servers that are in maintenance mode.
      3. Add one or more <loadBalanceEndPoints> elements to the <permitAction> element.

        If a <permitAction> element has more than one <loadBalanceEndPoints> element, the first <loadBalanceEndPoints> element acts as the primary set of destinations. All subsequent <loadBalanceEndPoints> elements act as failover destinations. The order in which the <loadBalanceEndPoints> elements are defined determines the failover priority.

      4. Add one or more <endpoint> elements to each <loadBalanceEndPoints> element.
      5. Add a destination attribute to each <endpoint> element. Set the destination attributes to either a server type or a cluster type.

        To specify a server-typed endpoint, specify server= followed by a four-part server specification, with parts delimited by a comma:

        <endpoint destination="server=collective_name,host_name,wlp.user.dir,server_name"/>
        • collective_name is the name of the collective where the server is a member.
        • host_name is the host address.
        • wlp.user.dir is the Liberty user directory on the host system where the server is defined. You can possibly use the ${wlp.user.dir} variable here, but it might not be appropriate. When this server.xml is evaluated, the value of ${wlp.user.dir} is the directory where the controller server is defined. This might not be the same directory where the member server is defined.
        • server_name is the server name.

        To specify a cluster-typed endpoint, specify cluster= followed by a two-part server specification, with parts delimited by a comma:

        <endpoint destination="cluster=collective_name,cluster_name"/>
        • collective_name is the name of the collective where the cluster is defined.
        • cluster_name is the cluster name.

        All parts of a server or cluster destination specification can use the wildcard character (*) to match any string. To use routing rules to route to multiple collectives, each collective must have a different name. If the connectorClusterName attribute of the <dynamicRouting> element is specified, the collective name is the value of the connectorClusterName attribute. If the connectorClusterName attribute of <dynamicRouting> is not specified, the collective name is the value that is used for the --collectiveName option when you run the collective create command. If the connectorClusterName attribute is not specified, and the --collectiveName option is not used, the collective name is defaultCollective.

      The following example shows a <permitAction> element with a server-typed endpoint:

      <dynamicRouting maxRetries="5" retryInterval="10000">
         <routingRules webServers="myWebServer">
            <routingRule order="100" matchExpression="URI LIKE '/myapp%'">
               <permitAction>
                  <loadBalanceEndPoints>
                     <endpoint destination="server=collective1,myhost,/opt/IBM/liberty/wlp/usr,member1"/>
                  </loadBalanceEndPoints>
               </permitAction>
            </routingRule>
         </routingRules>
      </dynamicRouting>
    • Specify the redirectAction action type to route a request to another location.
      1. Add the <redirectAction> element to a <routingRule> element.
      2. Add a location attribute to the <redirectAction> element. Set the location attribute to the new destination for the request.

      The following example shows a <redirectAction> element:

      <dynamicRouting maxRetries="5" retryInterval="10000">
         <routingRules webServers="myWebServer">
            <routingRule order="200" matchExpression="URI LIKE '/myapp%'">
               <redirectAction location="http://some.other.destination" />
            </routingRule>
         </routingRules>
      </dynamicRouting>
    • Specify the rejectAction action type to reject a request with a specific response code.
      1. Add the <rejectAction> element to a <routingRule> element.
      2. Add a code attribute to the <rejectAction> element. Set the code attribute to the HTTP response code to use when the request matches the rule. The code must be an error code that the web server supports.

      The following example shows a <rejectAction> element:

      <dynamicRouting maxRetries="5" retryInterval="10000">
         <routingRules webServers="myWebServer">
            <routingRule order="300" matchExpression="URI LIKE '/myapp%'">
               <rejectAction code="503" />
            </routingRule>
         </routingRules>
      </dynamicRouting>

Results

After the rules are defined, when a web server connects to the dynamic routing service, the rules that are associated with that web server, and the rules that are associated with all web servers, are delivered. The web server matches requests against the match expressions that are found in the rules. The expressions are evaluated according to the rule order, from lowest order to highest. The first rule with a matching expression is used. The action that is associated with the rule determines how the request is handled. If no rules are matched, the request load is balanced across all servers that can handle the request.

By default, when a request has session affinity, server selection is based on affinity. If an affinity server is found, that server is chosen and the routing rules are not evaluated. To enable routing rules to override affinity selection, the overrideAffinity attribute can be added to the <routingRules> element of the server.xml file.

Example

The following example combines multiple rules:

<dynamicRouting>
   <routingRules webServers="myWebServer">

      <routingRule order="100" matchExpression="URI LIKE '/myapp%'">
         <permitAction>
            <loadBalanceEndPoints>
               <endpoint destination="cluster=collective1,clusterB"/>
               <endpoint destination="cluster=collective2,clusterB"/>
            </loadBalanceEndPoints>
         </permitAction>
      </routingRule>


      <routingRule order="200" matchExpression="uri like '/AppX%' AND queryparm$test = 'true'">
         <permitAction allowMaintenanceModeServers="true">
            <loadBalanceEndPoints>
               <endpoint destination="server=collective1,*,*,member1"/>
            </loadBalanceEndPoints>
            <loadBalanceEndPoints>
               <endpoint destination="server=collective2,*,*,member1"/>
            </loadBalanceEndPoints>
         </permitAction>
      </routingRule>


      <routingRule order="300" matchExpression=" uri like '/AppX%' ">
         <permitAction>
            <loadBalanceEndPoints>
               <endpoint destination="cluster=collective1,clusterA"/>
               <endpoint destination="cluster=collective2,clusterA"/>
            </loadBalanceEndPoints>
         </permitAction>
      </routingRule>


      <routingRule order="400" matchExpression="URI LIKE '/myoldapp'">
         <redirectAction location="http://mysite/mynewapp" />
      </routingRule>


      <routingRule order="500" matchExpression="URI LIKE '/myveryoldapp'">
         <rejectAction code="503" />
      </routingRule>


   </routingRules>
 </dynamicRouting>

The routing rule with -order 100 limits the destinations where requests for /AppX are routed to two particular clusters across two collectives.

The routing rule with -order 200 shows an example of routing test requests to a server that is in maintenance mode. If test=true is added as a query parameter, then those requests are sent to server in collective1, even if that server is in maintenance mode.

The routing rule with -order 300 shows how to enable failover from one set of endpoints to another. Rule 300 routes all requests that match the expression to any clusters that can handle the request in collective1. If all clusters that can handle the request in collective1 are not available, clusters that can handle the request in collective2 are chosen for requests that match the rule expression.

The routing rule with -order 400 shows an example of a redirect rule.

The routing Rule with -order 500 shows an example of a reject rule.