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]
>>
>>