Forum Discussion

swjo_264656's avatar
swjo_264656
Icon for Cirrostratus rankCirrostratus
Aug 23, 2017

How to switching URI roundrobin based on data-group list

Hi guys.

 

My client request below things.

 

there are four server ( 119 120 121 122 )

 

When real client access apisky.whypaymore.co.kr and that request LB on server 119

 

switching URI by roundrobin.

 

1st request : 119 api31sky.whypaymore.co.kr

 

2nd request : 120 apisky.whypaymore.co.kr

 

3rd request : 121 apisky.whypaymore.co.kr

 

4th request : 122 apisky.whypaymore.co.kr

 

5th request : 119 api32sky.whypaymore.co.kr

 

6th request : 120 apisky.whypaymore.co.kr

 

7th request : 121 apisky.whypaymore.co.kr

 

8th request : 122 apisky.whypaymore.co.kr

 

9th request : 119 api33sky.whypaymore.co.kr

 

10th request : 120 apisky.whypaymore.co.kr

 

11th request : 121 apisky.whypaymore.co.kr

 

12th request : 122 apisky.whypaymore.co.kr

 

13th request : 119 api34sky.whypaymore.co.kr

 

14th request : 120 apisky.whypaymore.co.kr

 

15th request : 121 apisky.whypaymore.co.kr

 

16th request : 122 apisky.whypaymore.co.kr

 

how can I solve this thing?

 

5 Replies

  • Create 2 pools. POOL-1 contains 120, 121 and 122 with round robin method. POOL-2 contains 119.

    when HTTP_REQUEST {
    if { [HTTP::host] starts_with "apisky" } {
    pool POOL-1
    } else {
    pool POOL-2
    }
    }
    
  • Hi swjo,

    to overwrite the HTTP::host value based on the currently selected pool member (aka. just for pool member X.X.X.119), you have to use the

    HTTP_REQUEST_SEND
    event (triggered after pool member selection), filter on the selected pool member IP and finaly change the HTTP::host value to a random value based on a mod(rand())^4 calculation followed by an array lookup to retrive the HTTP::host names...

    when RULE_INIT {
        array set static::apisky {
            "0" "api31sky.whypaymore.co.kr"
            "1" "api32sky.whypaymore.co.kr"
            "2" "api33sky.whypaymore.co.kr"
            "3" "api34sky.whypaymore.co.kr"
        }
    
    }
    when HTTP_REQUEST_SEND {
        if { [LB::server addr] equals "X.X.X.119" } then {
            clientside {
                HTTP::host $static::apisky([expr { int( rand() * 100 ) % 4 }])
            }
        }
    }
    

    Note: The selection of the individual HTTP::host values in the example above is not a true "Round-Robin-Selection". Instead its more or less just a "Random-Selection". To implement a true "Round-Robin-Selection" you have to store a shared counter value into LTMs session-

    [table]
    so that each TMM core can access and also increase/rollover this information as needed. But in 9 out of 10 times a real "Round-Robin-Selection" isn't required and should therefor be avoided to save CPU cycles...

    Cheers, Kai

  • Hi Expert, Please correct me. If you have list of real client IP address, Then create IP list in data group, match with iRule & redirect to node 119.

     

    And rest connection should move to pool_A, where all the nodes are available.

     

    Does it makes sense?

     

    • swjo_264656's avatar
      swjo_264656
      Icon for Cirrostratus rankCirrostratus

      Hi f5_rock

       

      The client IP is random and can`t be set up as a data-group.

       

  • Hi swjo,

    To get a "true" Round-Robin mechanism for pool member selection and HOST-Header overwrites you have to implement some shared

    [table]
    -based RR counters, so that the individual TMM-cores (each of them will process a subset of the client connections) can become teamed. The shared RR counters will then be used to perform a handcrafted RR pool member selection followed by the RR based injection of the HOST-Header values.

    Note: You have to perform a handcrafted pool member selection, since LTM's build-in "Round Robin" load balancing algorythm does not share the RR counters across multiple TMM cores. It will just Round-Robin the request accordingly with that specific TMM instance...

    when RULE_INIT {
        array set static::apisky_hostheaders {
            "0" "api31sky.whypaymore.co.kr"
            "1" "api32sky.whypaymore.co.kr"
            "2" "api33sky.whypaymore.co.kr"
            "3" "api34sky.whypaymore.co.kr"
        }
        set static::apisky_hostheaders_count [array size static::apisky_hostheaders]
    }
    when HTTP_REQUEST {
    
         Fetching a list of the currently available pool members
    
        if { [set pool_active_members [active_members -list [LB::server pool]]] ne "" } then {
    
             Increasing the global RR counter for load balancing decission
    
            set pool_rr_counter [table incr "pool_rr_[LB::server pool]"]
    
             Reset the global RR counter for load balancing decission as needed.
    
            if { $pool_rr_counter > 1000000 } then {
                 The RR counter has exceded the maximum allowed value. Reset it back to 1
                set pool_rr_counter [table set "pool_rr_[LB::server pool]" 1] 
            }
    
             Performing a Load-Balancing decision based on the global RR counter value for load balancing decission and the list of currently available pool members.
            set pool_selected_member [lindex $pool_active_members [expr { ( $pool_rr_counter - 1 ) % [llength $pool_active_members]}]]
    
             Using the RR selected pool member as the current node
    
            pool [LB::server pool] member [lindex $pool_selected_member 0] [lindex $pool_selected_member 1]
    
             Increasing the global and per-pool_member RR counter for HOST-Header selection
    
            set member_rr_counter [table incr "member_rr_$pool_selected_member"]
    
             Reset the global and per-pool_member RR counter for HOST-Header selection as needed.
    
            if { $member_rr_counter >= 1000000 } then {
                 The RR counter has exceded the maximum allowed value. Reset it back to 1
                set member_rr_counter [table set "member_rr_$pool_selected_member" 1] 
            }
    
             Resolve the HOST-Header based on the values of $static::apisky_hostheaders() by selecting a modulus of the current RR counter value
            HTTP::host $static::apisky_hostheaders([expr { ( $member_rr_counter - 1 ) % $static::apisky_hostheaders_count }])
    
             Log the current node selection and choosen HOST-Header value
            log local0.debug "Current Node: $pool_selected_member | New HOST-Header: [HTTP::host]"  
    
        } else {
             The pool is unavailable...
            HTTP::respond 503 content "The pool is currently unavailable..." "Content-Type" "text/html"
        }
    }
    

    Log File:

    Aug 28 13:47:13 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 1.1.1.1%1 80 | New HOST-Header: api31sky.whypaymore.co.kr
    Aug 28 13:47:13 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 2.2.2.2%1 80 | New HOST-Header: api31sky.whypaymore.co.kr
    Aug 28 13:47:13 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 3.3.3.3%1 80 | New HOST-Header: api31sky.whypaymore.co.kr
    Aug 28 13:47:14 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api31sky.whypaymore.co.kr
    Aug 28 13:47:14 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 1.1.1.1%1 80 | New HOST-Header: api32sky.whypaymore.co.kr
    Aug 28 13:47:14 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 2.2.2.2%1 80 | New HOST-Header: api32sky.whypaymore.co.kr
    Aug 28 13:47:14 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 3.3.3.3%1 80 | New HOST-Header: api32sky.whypaymore.co.kr
    Aug 28 13:47:15 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api32sky.whypaymore.co.kr
    Aug 28 13:47:15 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 1.1.1.1%1 80 | New HOST-Header: api33sky.whypaymore.co.kr
    Aug 28 13:47:15 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 2.2.2.2%1 80 | New HOST-Header: api33sky.whypaymore.co.kr
    Aug 28 13:47:15 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 3.3.3.3%1 80 | New HOST-Header: api33sky.whypaymore.co.kr
    Aug 28 13:47:15 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api33sky.whypaymore.co.kr
    Aug 28 13:47:16 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 1.1.1.1%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    Aug 28 13:47:16 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 2.2.2.2%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    Aug 28 13:47:16 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 3.3.3.3%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    Aug 28 13:47:16 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    Aug 28 13:47:16 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    Aug 28 13:47:16 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 1.1.1.1%1 80 | New HOST-Header: api31sky.whypaymore.co.kr
    Aug 28 13:47:17 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 2.2.2.2%1 80 | New HOST-Header: api31sky.whypaymore.co.kr
    Aug 28 13:47:17 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 3.3.3.3%1 80 | New HOST-Header: api31sky.whypaymore.co.kr
    Aug 28 13:47:17 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api31sky.whypaymore.co.kr
    Aug 28 13:47:17 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 1.1.1.1%1 80 | New HOST-Header: api32sky.whypaymore.co.kr
    Aug 28 13:47:17 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 2.2.2.2%1 80 | New HOST-Header: api32sky.whypaymore.co.kr
    Aug 28 13:47:17 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 3.3.3.3%1 80 | New HOST-Header: api32sky.whypaymore.co.kr
    Aug 28 13:47:18 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api32sky.whypaymore.co.kr
    Aug 28 13:47:18 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 1.1.1.1%1 80 | New HOST-Header: api33sky.whypaymore.co.kr
    Aug 28 13:47:18 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 2.2.2.2%1 80 | New HOST-Header: api33sky.whypaymore.co.kr
    Aug 28 13:47:18 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 3.3.3.3%1 80 | New HOST-Header: api33sky.whypaymore.co.kr
    Aug 28 13:47:18 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api33sky.whypaymore.co.kr
    Aug 28 13:47:19 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 1.1.1.1%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    Aug 28 13:47:19 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 2.2.2.2%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    Aug 28 13:47:19 f5-02 debug tmm[25655]: Rule /Common/my_rule_rule : Current Node: 3.3.3.3%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    Aug 28 13:47:19 f5-02 debug tmm1[25655]: Rule /Common/my_rule_rule : Current Node: 4.4.4.4%1 80 | New HOST-Header: api34sky.whypaymore.co.kr
    

    Note: You can clearly see that pool members as well as the HOST-Header values are switched in a "true" Round-Robin manner, even in the case that multiple TMM core will procress this connection (tmm and tmm1 in my case).

    Cheers, Kai