Forum Discussion

Hamdi_Fersi_350's avatar
Hamdi_Fersi_350
Icon for Nimbostratus rankNimbostratus
Dec 10, 2015

Round-Robin based on client IP

Hi, Is there a way to make round-robin based on client source IP? And what is the difference between source and destination persistence profile? Thanks,

 

  • Hi Hamdi,

     

    round robin is the default load balancing method. As long as you do not turn on persistence for each new connection will a new pool member will be selected. To make sure connections from the same client IP address will be forwarded to the same pool member you want to apply source address affinity in the virtual server properties. A table will be build containing the client IPs accessing a virtual server and the mapping to a pool member. Whenenver a new connection from the same client IP is established within the persistence timeout the same pool member will be reselected and the timer will be initialized.

     

    Destination address affinity was implemented for balancing outgoing connections (ISP link load balancing) across routers. The table will contain the target IP address (destination) and information which next hop (router) was selected. So each new connection to the target will be forwarded through the same ISP link.

     

    Thanks, Stephan

     

  • Thanks for your answer Stephan, I want to have round robin based on source IP. I need to have an iRule to make the LB selects one pool member in a time (and persist it in 2 different places).

     

    • StephanManthey's avatar
      StephanManthey
      Icon for MVP rankMVP
      Hi Hamdi, what do you mean with "persist it in 2 different places"? Is it the same client using different virtual servers with different pools? By default the persistence table is build in context of the virtual servers and not applied globally. Thanks, Stephan
    • Hamdi_Fersi_350's avatar
      Hamdi_Fersi_350
      Icon for Nimbostratus rankNimbostratus
      I'm having 2 nodes per pool, and I have several clients opening at least 2 sessions towards the LB. What I need to have is that I want the client to be redirected to both of them, and not having the scenario where 1 client opening 2 sessions towards the same pool member. With a simple RR, you have 50% of chance to get your client redirected to different pool member. So I guess I would need to setup tables with keys as source:destination IP as unique value? Do you have any idea on how I can do that? Thanks,
    • StephanManthey's avatar
      StephanManthey
      Icon for MVP rankMVP
      That would be the opposite of a persistence. You are right, chances are good to forward (redirect is a different story) to the same real server (pool member) in case of two members only. You are right, it will require a table based approach to make sure to select a different pool member for each new connection a client creates. In the iRule I would create a list of available pool members with each new CLIENT_ACCEPTED event. Next step would be to lookup the table having the client IP as key and the index of the selected pool member as value. As long as the value is less than the number of the available pool members the value is increased and now used as a pointer to pick a new target from the list created in the first step and update the value. If the value is greater than the number of available pool members in the list it will be initialized to point to the first in the list. Select pool member. Increase and update the value. Probably one hour to write and test. Cheers, Stephan
  • What kind of application is this that the client opens at least 2 connections? Do they run on the same or different ports?

     

  • Hi, thanks for your answers. I'm having a couple of ESME clients (SMPP), trying to reach a pool of 2 SMSCs. I could find a solution for the ones that opens only one BIND session (by replicating the BIND message) through an amazing iRule i've found here: https://devcentral.f5.com/questions/balancing-smpp-traffic-based-on-recipient-address

     

    Now the only pending stuff is that I'm having some ESME that opens 2 sessions. The stuff with SMPP is that it's a sticky session. It will establish the session and then sends the SMS threads on it asynchronously. So I want client x.x.x.1 to open only one session in each pool member. I would probably go through Stephan proposition, but I'll need to get some time working on it. Do you guys have any samples? Thanks, BR//

     

  • Hi Hamdi,

     

    you may give the following code a try to start with:

     

    when CLIENT_ACCEPTED {
        set dynamic_member_list [active_members -list [LB::server pool]]
         build table with client IP as key and request counter as value; increase per new connection
        set member_pointer [table incr [IP::client_addr]]
        log local0. "member_pointer <$member_pointer>"
        if {$member_pointer >= [active_members [LB::server pool]]} {
            initialize table entry if client has sent more requests than poolmembers exist
           table set [IP::client_addr] 0
           set member_pointer 0
           log local0. "initialize member_pointer <$member_pointer>"
        }
        log local0. "pool [LB::server pool] member [lindex $dynamic_member_list $member_pointer]"
        eval pool [LB::server pool] member [lindex $dynamic_member_list $member_pointer]
    }
    

    I tried to keep it as generic as possible. Alternatively you may make it faster using static lists of pool members.

     

    Using tables may consume an unpredictable amount of memory and slow down the whole system as they are a shared resource. Thanks, Stephan