On Sun, Oct 7, 2012 at 6:37 PM, Baptiste <[email protected]> wrote:
> Actually, I would use the payload(<offset>,<length>) function with
> offset = 0 and length = 10 and it should work :)
> Like:
> stick-table type binary len 10 size 30k expire 1h
> stick on payload(0,10)

Thanks Baptiste / Guillaume.  This is a cool  feature and seems to be
exactly what I need.

However, I appear to have run into a bug (on haproxy-1.5-dev12).

I set up haproxy as follows:

listen mypool :8000
        mode tcp
        option tcplog
        balance roundrobin

        stick-table type binary len 36 size 30k expire 1h
        stick on payload(10,36)

        server pool1 server1.foo.com:8000
        server pool1 server2.foo.com:8000

For testing purpose (not sure if this is a relevant factor) the pool
members are "far away" from my load-balancer (which is currently
running on my Ubuntu laptop).

The problem is that in more than 50% of cases smp_fetch_payload() gets
called when no data has been read from the client.  I realize that
normally a load balancer would be in the same data-centre as the pool
members but it still seems like a bug.  Do you agree?  Actually when I
think about it - I'm not sure how relevant this even is because the
client *is* local to the load balancer and the problem occurs before
the upstream connection is even made so actually I think the upstream
latency may not be a factor at all.

I added some fprintf(stderr, ...) calls in relevant functions to try
to ascertain the good/bad code paths.

In the bad case (more often than not) I see this:

00000001:mypool.accept(0004)=0006 from [127.0.0.1:44809]
raw_sock_to_buf returned -1
process_runnable_tasks
process_session..
process_sticking_rules
stktable_fetch_key (16384, 0, 0)
sample_process
smp_fetch_payload [46] -> [0]
NO DICE

In the good case I see this:

00000001:mypool.accept(0004)=0006 from [127.0.0.1:44809]
raw_sock_to_buf returned 271
raw_sock_to_buf returned -1
process_runnable_tasks
process_session..
process_sticking_rules
stktable_fetch_key (16384, 0, 271)
sample_process
smp_fetch_payload [46] -> [271]
SUCCESS

The salient difference between good/bad cases I see is that in the bad
case raw_sock_to_buf gets called but receives a -1 return value which
results in smp_fetch_payload getting called when there is no data to
process.   When an *actual* read happens momentarily afterwards it
seems that process_sticking_rules never gets called again (looks like
it is a one-shot thing).

My guess is that the solution is to either: 1] not call
process_sticking_rules unless something has really been read 2] allow
process_sticking_rules to be called again when a genuine read happens.

Thanks,
Colm

>
> On Sat, Oct 6, 2012 at 6:36 PM, Guillaume Castagnino <[email protected]> wrote:
>> Le samedi 06 octobre 2012 17:11:31 kgardenia42 a écrit :
>>> Hi,
>>
>> Hi,
>>
>>> I have a custom TCP protocol I would like to load balance with
>>> haproxy.
>>>
>>> I'd like to implement a very simple stickiness algorithm based on the
>>> first (say) 10 bytes of client data (which contains a client
>>> identifier).  Source ip stickiness is not reliable enough.
>>>
>>> Is this a common use-case?  Has anyone else implemented this?     In
>>> proto_tcp.c I can see what appears to be a protocol analyzer concept
>>> which looks in the ballpark of what I need.  Does this seem the right
>>> way to go?  Can anyone give me any pointers on how to get started?
>>>
>>> Thanks.
>>
>> I think you can inspire you with the SSL ID stickyness explained here to
>> stick on data contained in packets:
>> http://blog.exceliance.fr/2011/07/04/maintain-affinity-based-on-ssl-
>> session-id/
>>
>> Instead of extracting the SSL ID, you extract your client identifier,
>> but this is more or less the same thing !
>>
>> regards,
>>
>> --
>> Guillaume Castagnino
>>     [email protected] / [email protected]
>>
>>

Reply via email to