Forum Discussion

Vincent_96516's avatar
Vincent_96516
Icon for Nimbostratus rankNimbostratus
Apr 17, 2012

Message based load balancing connection status

I am creating irules script to work under message based load balancing profile (mblb), the following are some issues I have (OS v.10.2.3):

 

(1) When there are no active members in the pool (all backend nodes are down), how can I close the client connection?

 

The following are the script I use:

 

when SERVER_CLOSED {

 

log local0. "Server connection closed to [IP::server_addr]."

 

 

if { [active_members [LB::server pool]] == 0 } {

 

clientside {

 

TCP::close

 

log local0. "TCP connection closed to [TCP::local_port]."

 

}

 

}

 

}

 

but the client connection is not closed. Are there any mblb related configuration for this?

 

 

(2) In one of our virtual server, server side will initial request, client will sent response. To maintain the backend connections (connections between LTM and server nodes), I set up a timer to broadcast ping message to all backend nodes as following:

 

 

when SERVER_CLOSED {

 

log local0. "Server connection closed to [IP::server_addr]."

 

 

if { [active_members [LB::server pool]] == 0 } {

 

clientside {

 

TCP::close

 

log local0. "TCP connection closed to [TCP::local_port]."

 

}

 

} else {

 

if { [info exists status_timer] } {

 

$timer exists, do nothing

 

} else {

 

log local0. "Set status timer"

 

set status_timer [after 30000 -periodic {

 

clientside {

 

foreach m [active_members -list [LB::server pool]] {

 

pool [LB::server pool] member [lindex $m 0] [lindex $m 1]

 

log local0. "send status ping to $m"

 

TCP::payload replace 0 0 $static::conn_ping

 

TCP::release 2

 

TCP::notify request

 

}

 

}

 

}]

 

}

 

}

 

}

 

 

The timer is set, but the ping message was not sent. Is there anything wrong with the code? $static::conn_ping is a 2 bytes ping message.

 

2 Replies

  • Hi Vincent,

     

     

    (1) When there are no active members in the pool (all backend nodes are down), how can I close the client connection?

     

     

    you may try this way...

     

    note that return value of active_members may not be the same as number of current active connection for the particular client connection.

     

     

    you could keep track that by using variable. here are 2 examples

     

     

    
     example I
    when CLIENT_ACCEPTED {
         check every second
        after 1000 -periodic {
            if { [active_members [LB::server pool]] == 0 } {
                reject
                log local0. "TCP connection closed to [TCP::local_port]."
            }
        }
    }
     example II
    when CLIENT_ACCEPTED {
        array set server_array {}
         check every second
        after 2000 -periodic {
            if { [array size server_array] == 0 } {
                reject
                log local0. "TCP connection closed to [TCP::local_port]."
            }
        }
    }
    when SERVER_CONNECTED {
        set s "[IP::remote_addr] [TCP::remote_port]"
        set server_array($s) 1
    }
    when SERVER_CLOSED {
        set s "[IP::remote_addr] [TCP::remote_port]"
        unset server_array($s)
    }

     

     

    (2) to periodically send somethig to server every 30 seconds, you can do as follow

     

     

     

     

    when SERVER_CONNECTED {

     

    send ping every 30 seconds

     

    after 30000 -periodic {

     

    you could add some code to check idletime here...

     

    TCP::respond $static::conn_ping

     

    }

     

    }

     

     

     

     

     

    May I ask what is your use case that you are using mblb profile for?

     

    This information would help us improve future version of mblb profile 🙂

     

     

    Thanks,

     

    Nat

     

    v
  • Thanks Nat for the suggestions.

     

     

    For issue (1), I used the example 1, and the issue is resolved.

     

     

    For issue (2), the example doesn't help. The main purpose for perioldically sending ping message is to handle node restart or new node join the pool when server side sending request message and waiting for response (I explain my requirement below).

     

     

    I am implement a high availablity solution for a finanical product.

     

    The communication is message based. One persistent client connection will be handled by multiple backend servers.

     

    The message format we are using is private (2 bytes binary header + binary payload). We will do load balancing based on one field in the message.

     

     

    The message can be either started from client side (client send request and wait for response) or server side (server send request and wait for response).

     

     

    The issue (2) I have is for server side sending request and waiting for response. When accepting client connection, I send ping message to each active member, so there will be a connection with every active member, each member can use this connection to send request. But if one member is brought down and restart, there will be no connection between LTM and the newly started member because the client will not send request and pool to the newly started node. So I tried to send ping message perioldically, so if there is new active member, a connection could be created with the member.

     

    I tried to set send ping message perioldically in CLIENT_ACCEPT:

     

    when CLIENT_ACCEPTED {

     

    log local0. "Client [IP::remote_addr]:[TCP::remote_port]-[TCP::local_port]"

     

    if {[active_members [LB::server pool]] < 1} {

     

    reject

     

    return

     

    }

     

    broadcast connect message to backend servers

     

    foreach m [active_members -list [LB::server pool]] {

     

    log local0. "send connect to $m"

     

    after 500

     

    pool [LB::server pool] member [lindex $m 0] [lindex $m 1]

     

    TCP::payload replace 0 0 $static::conn_ping

     

    TCP::release 2

     

    TCP::notify request

     

    }

     

     

    check every second

     

    after 2000 -periodic {

     

    if { [active_members [LB::server pool]] == 0 } {

     

    reject

     

    log local0. "TCP connection closed to [TCP::local_port]."

     

    }

     

    }

     

    Check whethere there is new member

     

    after 30000 -periodic {

     

    foreach am [active_members -list [LB::server pool]] {

     

    pool [LB::server pool] member [lindex $am 0] [lindex $am 1]

     

    log local0. "send status ping to $am"

     

    TCP::payload replace 0 0 $static::conn_ping

     

    TCP::release 2

     

    TCP::notify request

     

    }

     

    }

     

     

    TCP::collect

     

    }

     

     

    but I got error:

     

     

    Apr 18 12:52:01 local/tmm2 err tmm2[5551]: 01220001:3: TCL error: CAM-MBLB - Address in use (line 2) invoked from within "pool [LB::server pool] member [lindex $am 0] [lindex $am 1]" ("foreach" body line 2) invoked from within "foreach am [active_members -list [LB::server pool]] { pool [LB::server pool] member [lindex $am 0] [lindex $am 1] log local0. ..."

     

     

    Is there any way to solve this kind of issue?