Forum Discussion

Narendra_26827's avatar
Narendra_26827
Icon for Nimbostratus rankNimbostratus
Jul 20, 2011

iRule to retry with modulus operator

Hi,

We have 4 pools and we are redirecting the request to each pool by calculating modulus of crc32 value of an http header id. I have written the following iRule for that :

In http header we will get objectId and we will do crc32 and get a value and after we do a modulus to redirect to appropriate pool (and further redirection to appropriate pool via HTTP::uri). So that all same objectId remain in all same subsystem pools. From starting we know we have 3 nodes in each pool.

when HTTP_REQUEST {

set uri [HTTP::uri]

if { [string tolower $uri] contains "/api/gateway" or [string tolower $uri] contains "/api/channel" or [string tolower $uri] contains "/api/space" }

{

set orgid [crc32 [HTTP::header objectId]]

set key [expr $orgid % 3]

log "mod value is $key"

if { $key == 0 }

{

log "Redirecting to Pool 0"

switch -glob [string tolower $uri] {

"/api/channel*" { pool channel-pool member 192.168.159.133 8088 }

"/api/space*" { pool space-pool member 192.168.159.133 8089 }

"/api/gateway*" { pool gateway-pool member 192.168.159.133 8087 }

default{ pool default_pool member 192.168.159.133 80 }

}

} elseif { $key == 1 }

{

log "Redirecting Pool 1"

switch -glob [string tolower $uri] {

"/api/channel*" { pool channel-pool member 192.168.159.134 8088 }

"/api/space*" { pool space-pool member 192.168.159.134 8089 }

"/api/gateway*" { pool gateway-pool member 192.168.159.134 8087 }

default { pool default_pool member 192.168.159.134 80 }

}

} elseif { $key == 2 }

{

log "Redirecting to Pool 2"

switch -glob [string tolower $uri] {

"/api/channel*" { pool channel-pool member 192.168.159.135 8088 }

"/api/space*" { pool space-pool member 192.168.159.135 8089 }

"/api/gateway*" { pool gateway-pool member 192.168.159.135 8087 }

default { pool default_pool member 192.168.159.135 80 }

}

}

}

}

Now we have a functionality that if one member in any pool went down it will not send request to the same node across all pools. But how can we can decrease the no. from 3 to 2 or some other value if it finds any member in any pool as down.

If anybody can help me on this.

Thanks.

  • I have created the following iRule. The active member list order is always different during every event. Can we set it to a proper order? does my below logic of unsetting variables which stores active members list will work?

    
    
    when HTTP_REQUEST {
    
    set uri [HTTP::uri]
    
    if { [string tolower $uri] contains "/api/gateway" or [string tolower $uri] contains "/api/channel" or [string tolower $uri] contains "/api/space" }
    {
    set orgid [crc32 [HTTP::header objectId]]
    set key [expr $orgid % [active_members default_pool]]
    
    set default_member [active_members -list default_pool]
    set channel_member [active_members -list channel-pool]
    set gateway_member [active_members -list gateway-pool]
    set space_member [active_members -list space-pool]
    
    log "CRC32 value $orgid"
    log "Mod value $key"
    
    switch -glob [string tolower $uri] {
    "/api/channel*" {
    log "[lindex [lindex $channel_member $key]  0] [lindex [lindex $channel_member $key]  1]"
    pool channel-pool member [lindex [lindex $channel_member $key]  0] [lindex [lindex $channel_member $key]  1]
    unset channel_member
    }
    "/api/space*" {
    log "[lindex [lindex $space_member $key]  0] [lindex [lindex $space_member $key]  1]"
    pool space-pool member [lindex [lindex $space_member $key]  0] [lindex [lindex $space_member $key]  1]
    unset space_member
    }
    "/api/gateway*" {
    log "[lindex [lindex $gateway_member $key]  0] [lindex [lindex $gateway_member $key]  1]"
    pool gateway-pool member [lindex [lindex $gateway_member $key]  0] [lindex [lindex $gateway_member $key]  1] 
    unset gateway_member
    }
    default {
    log "[lindex [lindex $channel_member $key]  0] [lindex [lindex $channel_member $key]  1]"
    pool default_pool member [lindex [lindex $default_member $key]  0] [lindex [lindex $default_member $key]  1]
    unset default_member
    }
    }
    
    }
    }
    
    when LB_FAILED {
    
    set uri [HTTP::uri]
    
    if { [HTTP::header exists "objectId"] }
    {
    set orgid_new [crc32 [HTTP::header objectId]]
    set newkey [expr $orgid_new % [active_members default_pool]]
    
    set default_member_new [active_members -list default_pool]
    set channel_member_new [active_members -list channel-pool]
    set gateway_member_new [active_members -list gateway-pool]
    set space_member_new [active_members -list space-pool]
    
    
    
    switch -glob [string tolower $uri] {
    "/api/channel*" {
    log "[lindex [lindex $channel_member_new $newkey]  0] [lindex [lindex $channel_member_new $newkey]  1]"
    LB::reselect pool channel-pool member [lindex [lindex $channel_member_new $newkey]  0] [lindex [lindex $channel_member_new $newkey]  1]
    unset channel_member_new
    }
    "/api/space*" {
    log "[lindex [lindex $space_member_new $newkey]  0] [lindex [lindex $space_member_new $newkey]  1]"
    LB::reselect pool space-pool member [lindex [lindex $space_member_new $newkey]  0] [lindex [lindex $space_member_new $newkey]  1]
    unset space_member_new
    }
    "/api/gateway*" {
    log "[lindex [lindex $gateway_member_new $newkey]  0] [lindex [lindex $gateway_member_new $newkey]  1]"
    LB::reselect pool gateway-pool member [lindex [lindex $gateway_member_new $newkey]  0] [lindex [lindex $gateway_member_new $newkey]  1]
    unset gateway_member_new
    }
    default {
    log "[lindex [lindex $default_member_new $newkey]  0] [lindex [lindex $default_member_new $newkey]  1]"
    LB::reselect pool default_pool member [lindex [lindex $default_member_new $newkey]  0] [lindex [lindex $default_member_new $newkey]  1]
    unset default_member_new
    }
    }
    }
    }
    
    

    If any body can provide a hint or suggestion. Thanks.

  • Hi Narendra,

     

    I have never tried this but I think you might be able to sort using the following command

     

     

     

    set default_member [lsort -stride 2 [active_members -list default_pool]]

     

    set channel_member_new [lsort -stride 2 [active_members -list channel-pool]]

     

    set gateway_member_new [lsort -stride 2 [active_members -list gateway-pool]]

     

    set space_member_new [lsort -stride 2 [active_members -list space-pool]]

     

     

     

    I don't see an issue with using unset in your code

     

     

    Bhattman