Forum Discussion

Festus_50639's avatar
Festus_50639
Icon for Nimbostratus rankNimbostratus
Dec 01, 2008

"Select pool based on uri content" iRule doesn't seem to be working

Good morning,

 

 

I have an iRule that is designed to select a pool based on a string found in the uri and it doesn't seem to be working. I have a log that collects the uri for reference. The "test" rule I have in place that searches the uri and creates the "destination pool name" seems to be creating the pool name correctly, but when I put the "action" rule into place the http request hangs. Background and iRules are provided below.

 

 

Background:

 

 

 

-The VIP is listening on port 80 and has a default pool listening on 8981

 

 

-The web application being load balanced is Tibco ESB

 

 

-There are 25 separate services that are supported by this application and all are listening on different ports

 

 

-Individual pools are created with basic http monitor showing all pool members as "up"

 

 

-Our pools have a naming convention that has a string before and after the service name. (i.e. esb__pool)

 

 

-Use of "uri" and "test" rules yield the following log entries:

 

Dec 1 08:37:28 tmm tmm[1097]: Rule esb_pool-uri-log : ====VIP uri request is /eProxy/service/CreditCardService?wsdl====

 

Dec 1 08:37:28 tmm tmm[1097]: Rule esb_pool-mgr_test : ==ESB Tibco: Requested pool name is esb_CreditCardService_pool==

 

 

-Use of the "uri" and "action rules yield the following log entries:

 

ec 1 08:43:36 tmm tmm[1097]: Rule esb_pool-uri-log : ====VIP uri request is /eProxy/service/CreditCardService?wsdl====

 

Dec 1 08:43:36 tmm tmm[1097]: Rule esb_pool-mgr_action : ==ESB Tibco: Requested pool name is esb_CreditCardService_pool==

 

 

 

iRules:

 

 

"uri logging rule"

 

 

rule esb_pool-uri-log {

 

when HTTP_REQUEST {

 

set esb_uri [HTTP::uri]

 

log local0. "===="

 

log local0. "====VIP uri request is $esb_uri===="

 

 

}

 

}

 

++++++++++++++++++++++++++

 

 

"pool selection test rule"

 

rule esb_pool-mgr_test {

 

when HTTP_REQUEST {

 

set front "esb_"

 

set back "_pool"

 

set svc_uri [getfield [HTTP::uri] ? 1]

 

set svc_name [getfield $svc_uri "dir1/service/" 2]

 

set pool_name [concat $front$svc_name$back]

 

log local0. "==ESB Tibco: Requested pool name is $pool_name=="

 

}

 

}

 

++++++++++++++++++++++++++

 

 

"pool selection action rule"

 

rule esb_pool-mgr_action {

 

when HTTP_REQUEST {

 

set front "esb_"

 

set back "_pool"

 

set svc_uri [getfield [HTTP::uri] ? 1]

 

set svc_name [getfield $svc_uri "dir1/service/" 2]

 

set pool_name [concat $front$svc_name$back]

 

log local0. "==ESB Tibco: Requested pool name is $pool_name=="

 

 

if { [catch { pool $pool_name } ] } {

 

 

log local0. "====ERROR: Attempting to assign traffic to non-existant pool $pool_name===="

 

log local0. "====Sending traffic to default esb pool===="

 

pool esb_8981_pool

 

}

 

}

 

}

 

 

Is there something I am missing that is not sending the traffic to the correct pool?

 

 

Thanks,

 

Kevin

 

 

 

14 Replies

  • The previous rule and its associated data class list have undergone some transformations.

     

     

    We now have a simplified data class list using only the service name. I will provide an example below using the actual class name and dummy content.

     

     

    esb_svcname_class {

     

    "service1"

     

    "service2"

     

    "service3"

     

    "service4"

     

    }

     

     

    In addition to streamlining the class, the logic determining whether both services on the same server are up was replaced by putting two health monitors on each pool and requiring that all health monitors be successful in order for a node to be considered "up".

     

     

    The current rule is as follows. However, the requests are being sent to the VIP port rather than the appropriate port for the specific pool.

     

     

    when HTTP_REQUEST {

     

     

    log local0. "==ESB URI requested is [HTTP::uri]=="

     

     

    set svc_uri [string tolower [getfield [HTTP::uri] ? 1]]

     

    set svc_name [getfield $svc_uri "eproxy/service/" 2]

     

    set front "esb_"

     

    set back "_pool"

     

    set svc_pool [concat $front$svc_name$back]

     

     

    log local0. "--Service name is $svc_name--"

     

    log local0. "--Service pool is $svc_pool--"

     

     

    if { [ matchclass $::esb_svcname_class contains $svc_name] } {

     

    pool $svc_pool

     

    log local0. "--Request sent to $svc_pool--"

     

    } else {

     

    pool esb_policyagent_pool

     

    log local0. "==ESB Service $svc_name was not defined. Policy Agent pool selected=="

     

    }

     

    }

     

     

    Am I missing an eval or LB::select to make sure I'm sending the traffic to the port on the selected pool member instead of the VIP port?

     

     

    Thanks,

     

    Kevin

     

  • Are you sure that port translation is enabled on the VIP? As long as you are sending it to the correct pool within the iRule and port translation is on, the serverside connection should go to the right port. The only way to override that from within the rule that I can think of would be to specifically call out the node and port with a node command, which you don't appear to be doing...

     

     

    Denny
  • What port(s) are the pool members defined on? Can you add a log line or two and post the logs from a failure?

     
     when LB_SELECTED { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: LB info: [LB::server]" 
     } 
     when SERVER_CONNECTED { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: server info: [IP::server_addr]:[TCP::server_port]" 
     } 
     

    Also, you can use HTTP::query to get the query string value. So you could remove "set svc_uri [string tolower [getfield [HTTP::uri] ? 1]]" and use HTTP::query.

    Aaron