Forum Discussion

Shu_97237's avatar
Shu_97237
Icon for Nimbostratus rankNimbostratus
Jul 30, 2012

Message-based load balancing problem

Hi,

 

 

 

So far, it has been a hassle for me to configure MBLB. (see my first question:

https://devcentral.f5.com/Community/GroupDetails/tabid/1082223/aft/2163630/asg/50/Default.aspx,

 

That problem was essentially caused by error in network configuration. As https://devcentral.f5.com/wiki/iRules.TCP__notify.ashx indicated, "the USER_REQUEST event will not be raised until the server-side TCP connection is complete".

 

 

 

However, the current problem is that it took a long time for the response sent by servers to reach the client. I'm pretty sure the server sent the response back successfully without delay (send() returned actual number of bytes sent). I also tested the setting with http GET sent with a browser. The requests were properly forwarded to the pool and got a response (error response since the server doesn't support http) from the server quickly. What could be the problem?

 

 

 

Thanks!

 

 

 

Shu

 

  • Got some inspiration from this https://devcentral.f5.com/Forums/tabid/53/afv/topic/aff/5/aft/2161558/Default.aspx So I tested by removing some TCP::collect from the irules. The delayed response problem disappeared after I commented the TCP::collect in rules handling SERVER_CONNECTED event. However I realized it was not message-based load balancing but connection based load balancing. I did add "mblb" profile to the virtual server. Obviously the irules I wrote to extract individual messages didn't work. But why?

     

     

     

    Can someone explain to me when I should use TCP::collect? I found some examples call TCP::collect almost in every event declaration, which I don't understand. I personally think I only need to call it in CLIENT_ACCEPTED and CLIENT_DATA.

     

     

     

    Below are my current irules:

     

     

     

    when CLIENT_ACCEPTED {

     

    set client_closed 0

     

    TCP::collect

     

    }

     

     

     

    periodically checks if the client connection closed, if so, also closes associated server connection.

     

    when CLIENT_CLOSED {

     

    set client_closed 1

     

    }

     

     

     

    Triggered when a connection has been established with the target node

     

    when SERVER_CONNECTED {

     

    after 1000 -periodic if {$client_closed} {TCP::close}

     

    TCP::collect

     

    }

     

     

     

    when CLIENT_DATA {

     

    binary scan [TCP::payload] II head rlen

     

    if {($head & 0x3) == 1} {

     

    if {[TCP::payload length] < [expr {8 + $rlen}]} {

     

    TCP::collect [expr {$rlen + 8 - [TCP::payload length]}]

     

    return

     

    }

     

    }

     

     

    TCP::release [expr {$rlen + 8}]

     

    TCP::notify request

     

    TCP::collect

     

    }

     

     

     

    when USER_REQUEST {

     

    pool my_pool

     

    }

     

     

     

  • Hi Shu,

     

     

    when mblb profile is used, USER_REQUEST event will not be fired.

     

    you may try moving pool command to CLIENT_DATA (above the TCP::release)

     

     

    Nat
  • Thanks, Nat! You made my day. Moving pool command to CLIENT_DATA is the right solution. Unfortunately, I couldn't find this on the documents I've read so far and F5 support didn't even want to look at the simple irules I wrote.

     

     

    Thank you Michael too. I think what you said is a general principle to use TCP::collect. For MBLB, one may have to call TCP::collect in CLIENT_DATA to extract single messages.

     

     

  • Hi Shu, the correct iRule would it?

    when CLIENT_ACCEPTED {

    set client_closed 0 TCP::collect

    }

    when CLIENT_CLOSED {

    set client_closed 1

    }

    when SERVER_CONNECTED { after 1000 -periodic if {$client_closed} {TCP::close} }

    when CLIENT_DATA {

    binary scan [TCP::payload] II head rlen

    if {($head & 0x3) == 1} {

    if {[TCP::payload length] < [expr {8 + $rlen}]} {
    
        TCP::collect [expr {$rlen + 8 - [TCP::payload length]}]
    
        return
    
    }
    

    }

    pool my_pool

    TCP::release [expr {$rlen + 8}]

    TCP::notify request

    TCP::collect

    }