Forum Discussion

KT_271103's avatar
KT_271103
Icon for Nimbostratus rankNimbostratus
Sep 21, 2016

Irule expaination

Hi,

 

Can anyone explain below irule code

 

when HTTP_REQUEST { set pool_nm "web_8080_" set key [expr {[crc32 [substr [HTTP::uri] 0 "?"]] % 3}] append pool_nm $key if { [active_members "$pool_nm"] } { pool "$pool_nm" } else { pool web_proxy } }

 

2 Replies

  • Gist:

    You should be having multiple pools that start with "web_8080_{some-value-here}". Traffic is sent to the pool identified by "web_8080_{some-value-here}" if there are available members and if not, to the pool: web_proxy

    A bit more detail:

    [substr [HTTP::uri] 0 "?"] - if you have a string like this in the URI:

    /index.jsp?user=test&login=check
    -
    /index.jsp
    will be the answer and this will be subjected to crc32 and then the remainder of the value when divided by 3 is used as "key" which is then used as "{some-value-here}" in the pool name as noted in the 1st line of this comment.

    when HTTP_REQUEST { 
    set pool_nm "web_8080_" 
    set key [expr {[crc32 [substr [HTTP::uri] 0 "?"]] % 3}] 
    append pool_nm $key 
    if { [active_members "$pool_nm"] } { 
    pool "$pool_nm" 
    } else { pool web_proxy 
    } 
    }
    
  • Hi KT,

    the provided iRule provides a load balancing decission for your Web Proxy Servers based on a Euclidean division aka. Modulo operation on a CRC32 checksum of an URI value.

    The line...

    set key [expr {[crc32 [substr [HTTP::uri] 0 "?"]] % 3}] 
    

    ... is passing the requested URI (in the case of HTTP Web Proxy Traffic it will be a full URL like http://www.domain.de/folder/file.ext or for HTTPS it will be just www.domain.de:443) to a CRC32 function, which will result in a random but reproducable 32bit value for each given URI. The 32bit value is then passed to a Modulo of 3 calculation resulting in an $key value of either 0, 1, or 2.

    The lines...

    set pool_nm "web_8080_" 
    append pool_nm $key
    

    ... will contrust a pool name based on a fixed string and the previously calculated number (results are either web_8080_0, web_8080_1, web_8080_2 or web_8080_3).

    The lines...

    if { [active_members "$pool_nm"] } { 
        pool "$pool_nm" 
    } else { 
        pool web_proxy
    }
    

    ... will then check the availability of the the constructed pool name and if it has online members, it will be selected. If the contrusted pool doesn't have online members, the default pool "web_proxy" will be selected.

    Alternative Syntax:

    The provided iRule is somewhat outdated. It can now safely be replace with a rather simple...

    when HTTP_REQUEST {
        pool web_proxy
        persist carp [URI::path [HTTP::path]]
    }
    

    Recommendation:

    You have to keep in mind that a modulo(CRC32(HTTP::uri)) and also CARP Load Balancing decission does not work well for HTTP Proxy Traffic. Since it would require a OneConnect Profile or a manual LB::detach on every single request to allow subsequent LB decissions on a single TCP connection. This requirement will unfortunately break any "Session-Based-Authentication" (aka. NTLM, Kerberos, Negotiate Authentication).

    Without OneConnect Profile or a manual LB::detach on every request, just the first HTTP request is getting balanced correctly and subsequent request send over the same Keep-Alive TCP connection will just stick to the initial selected node...

    Personally I would rather then use a more traditional LB algorythm with session presistence (e.g. SOURCE_IP) , to balance the HTTP Proxy Servers. Its far easier to implement, does result in almost the same results and has even less side effects...

    Cheers, Kai