Hi.
I try to protect an backend server against a overload within a master/master
setup.
The test setup looks like this
lb1: 8081 \
-hap-dest: 8080
lb2: 8082 /
When I now call lb1 with curl the "tracker/quota1" gpc is increased and the
second request is denied.
The problem is that the peer on lb2 does not get the counter data to protect
the backend on lb2 too.
Please can anybody help me to fix my mistake and find a proper solution.
```
curl -v http://127.0.0.1:8081/; curl -v http://127.0.0.1:8081
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< dest_dst_conn: 1
< content-length: 0
<
* Connection #0 to host 127.0.0.1 left intact
####
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8081
< HTTP/1.1 403 Forbidden
< content-length: 93
< cache-control: no-cache
< content-type: text/html
```
``` lb1
echo "show peers;show table tracker/quota1;show table tracker/quota2"|socat -
tcp4-connect:127.0.0.1:9990
0x55bb71554dc0: [05/Dec/2021:10:27:17] id=tracker disabled=0 flags=0x33
resync_timeout=<PAST> task_calls=5
0x55bb71558350: id=tracker(remote,inactive) addr=127.0.0.1:20001
last_status=NAME last_hdshk=5m36s
reconnect=<PAST> heartbeat=<NEVER> confirm=0 tx_hbt=0 rx_hbt=0 no_hbt=0
new_conn=1 proto_err=0 coll=0
flags=0x0
shared tables:
0x55bb7156f1e0 local_id=2 remote_id=0 flags=0x0 remote_data=0x0
last_acked=0 last_pushed=0 last_get=0 teaching_origin=0 update=0
table:0x55bb71556a50 id=tracker/quota1 update=3 localupdate=3
commitupdate=0 refcnt=1
Dictionary cache not dumped (use "show peers dict")
0x55bb7156f090 local_id=1 remote_id=0 flags=0x0 remote_data=0x0
last_acked=0 last_pushed=0 last_get=0 teaching_origin=0 update=0
table:0x55bb71556c60 id=tracker/quota2 update=2 localupdate=2
commitupdate=0 refcnt=1
Dictionary cache not dumped (use "show peers dict")
0x55bb71557300: id=h1(local,inactive) addr=127.0.0.1:20000 last_status=NONE
last_hdshk=<NEVER>
reconnect=<NEVER> heartbeat=<NEVER> confirm=0 tx_hbt=0 rx_hbt=0
no_hbt=0 new_conn=0 proto_err=0 coll=0
flags=0x0
shared tables:
0x55bb7156f230 local_id=2 remote_id=0 flags=0x0 remote_data=0x0
last_acked=0 last_pushed=0 last_get=0 teaching_origin=0 update=0
table:0x55bb71556a50 id=tracker/quota1 update=3 localupdate=3
commitupdate=0 refcnt=1
Dictionary cache not dumped (use "show peers dict")
0x55bb7156f0e0 local_id=1 remote_id=0 flags=0x0 remote_data=0x0
last_acked=0 last_pushed=0 last_get=0 teaching_origin=0 update=0
table:0x55bb71556c60 id=tracker/quota2 update=2 localupdate=2
commitupdate=0 refcnt=1
Dictionary cache not dumped (use "show peers dict")
# table: tracker/quota1, type: string, size:100, used:1
0x55bb71772888: key=0 use=0 exp=53297 server_id=0 gpc0=1
# table: tracker/quota2, type: string, size:100, used:1
0x55bb71772958: key=0 use=0 exp=53297 server_id=0 gpc1=0
```
``` lb2
echo "show peers;show table tracker/quota1;show table tracker/quota2"|socat -
tcp4-connect:127.0.0.1:9991
0x5618ae836dc0: [05/Dec/2021:10:27:12] id=tracker disabled=0 flags=0x33
resync_timeout=<PAST> task_calls=5
0x5618ae83a350: id=tracker(remote,inactive) addr=127.0.0.1:20000
last_status=NAME last_hdshk=5m31s
reconnect=<PAST> heartbeat=<NEVER> confirm=0 tx_hbt=0 rx_hbt=0 no_hbt=0
new_conn=2 proto_err=0 coll=0
flags=0x0
shared tables:
0x5618ae8511e0 local_id=2 remote_id=0 flags=0x0 remote_data=0x0
last_acked=0 last_pushed=0 last_get=0 teaching_origin=0 update=0
table:0x5618ae838a50 id=tracker/quota1 update=0 localupdate=0
commitupdate=0 refcnt=1
Dictionary cache not dumped (use "show peers dict")
0x5618ae851090 local_id=1 remote_id=0 flags=0x0 remote_data=0x0
last_acked=0 last_pushed=0 last_get=0 teaching_origin=0 update=0
table:0x5618ae838c60 id=tracker/quota2 update=0 localupdate=0
commitupdate=0 refcnt=1
Dictionary cache not dumped (use "show peers dict")
0x5618ae839300: id=h2(local,inactive) addr=127.0.0.1:20001 last_status=NONE
last_hdshk=<NEVER>
reconnect=<NEVER> heartbeat=<NEVER> confirm=0 tx_hbt=0 rx_hbt=0
no_hbt=0 new_conn=0 proto_err=0 coll=0
flags=0x0
shared tables:
0x5618ae851230 local_id=2 remote_id=0 flags=0x0 remote_data=0x0
last_acked=0 last_pushed=0 last_get=0 teaching_origin=0 update=0
table:0x5618ae838a50 id=tracker/quota1 update=0 localupdate=0
commitupdate=0 refcnt=1
Dictionary cache not dumped (use "show peers dict")
0x5618ae8510e0 local_id=1 remote_id=0 flags=0x0 remote_data=0x0
last_acked=0 last_pushed=0 last_get=0 teaching_origin=0 update=0
table:0x5618ae838c60 id=tracker/quota2 update=0 localupdate=0
commitupdate=0 refcnt=1
Dictionary cache not dumped (use "show peers dict")
# table: tracker/quota1, type: string, size:100, used:0
# table: tracker/quota2, type: string, size:100, used:0
```
I run haproxy with this commands.
```
# hap-dest
podman run --rm --name haproxy-dest -v /datadisk/haproxy-peer-test:/mnt
--network host --publish 8080:8080 haproxy:2.4 -- haproxy -f
/mnt/haproxy-dest/haproxy-dest.cfg
# lb1
podman run -d --rm --name haproxy-lb1 -v /datadisk/haproxy-peer-test:/mnt
--network host --publish 8081:8081 --publish 9800:9800 --publish 20000:20000
haproxy:2.4 haproxy -f /mnt/haproxy-lb1/haproxy-lb1.cfg
# lb2
podman run -d --rm --name haproxy-lb2 -v /datadisk/haproxy-peer-test:/mnt
--network host --publish 8082:8082 --publish 9801:9801 --publish 20001:20001
haproxy:2.4 haproxy -f /mnt/haproxy-lb2/haproxy-lb2.cfg
podman exec haproxy-dest haproxy -vv
HAProxy version 2.4.9-f8dcd9f 2021/11/24 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.9.html
Running on: Linux 5.11.0-40-generic #44~20.04.2-Ubuntu SMP Tue Oct 26 18:07:44
UTC 2021 x86_64
...
```
Attached also the configs.
Thanks for any help.
Best regards
Alexglobal
log stdout format short daemon debug
maxconn 20
defaults
timeout connect 1s
timeout server 1s
timeout client 1s
frontend http
mode http
log global
log-format "[%tr] %ST %B %CC %CS %tsc %hr %hs %{+Q}r"
# declare capture response len 4
capture response header dst_conn len 4
bind :::8080 v4v6
default_backend nginx
# The "nginx" proxy pretends to be the nginx backend for simplicity. The
returned header
# depends on whether the path ends in ".php", or not.
backend nginx
mode http
# bind :::8081
http-request return status 200 hdr DEST_dst_conn "%[dst_conn]"
global
log stdout format short daemon
stats socket [email protected]:9990 level admin expose-fd listeners
localpeer h1
defaults
mode http
option httplog
timeout connect 1s
timeout server 5s
timeout client 5s
listen public_www
bind 127.0.0.1:9800
stats enable
stats uri /stats
frontend http
log global
#log-format "[%tr] %ST %B %CC %CS %tsc %hr %hs %{+Q}r"
declare capture response len 4
capture response header DEST_dst_conn len 25
tcp-request inspect-delay 10s
#acl pixel_save sc0_clr_gpc0(tracker/quota) ge 1
#acl pixel_deny sc0_gpc0_rate(tracker/quota) gt 1
# Track the request in 'quota' stick table for the key "res.hdr(customer)".
# http-request track-sc0 srv_conn(bk_customer/haproxy-dest1) table
tracker/quota1
# http-request track-sc1 srv_conn(bk_customer/haproxy-dest2) table
tracker/quota2
# deny when more then 2 requests
# http-request deny if {
srv_conn(bk_customer/haproxy-dest1),table_gpc0(tracker/quota1) ge 1 }
# http-request deny if {
srv_conn(bk_customer/haproxy-dest2),table_gpc1(tracker/quota2) ge 2 }
#http-request deny if pixel_deny
# And increase the counter.
# http-request sc-inc-gpc0(0)
# http-request sc-inc-gpc1(0)
# http-request track-sc0 int(1) table p/t1
# http-request set-var(req.gpc0) sc_inc_gpc0(0)
# http-request set-var(req.gpc0) sc_get_gpc0(0,p/t2),add(req.gpc0)
# http-request set-var(req.gpc0) sc_get_gpc0(0,p/t3),add(req.gpc0)
# http-request return hdr x-out %[var(req.gpc0)]
bind :::8081 v4v6
default_backend bk_customer
backend bk_customer
mode http
balance roundrobin
log global
http-request track-sc0 srv_conn(bk_customer/haproxy-dest1) table
tracker/quota1
http-request track-sc1 srv_conn(bk_customer/haproxy-dest2) table
tracker/quota2
http-request deny if {
srv_conn(bk_customer/haproxy-dest1),table_gpc0(tracker/quota1) ge 1 }
http-request deny if {
srv_conn(bk_customer/haproxy-dest2),table_gpc1(tracker/quota2) ge 2 }
http-request sc-inc-gpc0(0)
http-request sc-inc-gpc1(0)
server haproxy-dest1 127.0.0.1:8080
server haproxy-dest2 127.0.0.1:8080
peers tracker
#log global
log stdout format raw daemon debug
table quota1 type string size 100 expire 1m store server_id,gpc0
table quota2 type string size 100 expire 1m store server_id,gpc1
bind 127.0.0.1:20000 v4v6
server h1 #alex-TUXEDO-Book-XP1511
server tracker 127.0.0.1:20001 check
global
log stdout format short daemon
stats socket [email protected]:9991 level admin expose-fd listeners
localpeer h2
defaults
mode http
option httplog
timeout connect 1s
timeout server 5s
timeout client 5s
listen public_www
bind 127.0.0.1:9801
stats enable
stats uri /stats
frontend http
log global
#log-format "[%tr] %ST %B %CC %CS %tsc %hr %hs %{+Q}r"
declare capture response len 4
capture response header DEST_dst_conn len 25
tcp-request inspect-delay 10s
#acl pixel_save sc0_clr_gpc0(tracker/quota) ge 1
#acl pixel_deny sc0_gpc0_rate(tracker/quota) gt 1
# Track the request in 'quota' stick table for the key "res.hdr(customer)".
# http-request track-sc0 srv_conn(bk_customer/haproxy-dest1) table
tracker/quota1
# http-request track-sc1 srv_conn(bk_customer/haproxy-dest2) table
tracker/quota2
# deny when more then 2 requests
# http-request deny if {
srv_conn(bk_customer/haproxy-dest1),table_gpc0(tracker/quota1) ge 1 }
# http-request deny if {
srv_conn(bk_customer/haproxy-dest2),table_gpc1(tracker/quota2) ge 2 }
#http-request deny if pixel_deny
# And increase the counter.
# http-request sc-inc-gpc0(0)
# http-request sc-inc-gpc1(0)
# http-request track-sc0 int(1) table p/t1
# http-request set-var(req.gpc0) sc_inc_gpc0(0)
# http-request set-var(req.gpc0) sc_get_gpc0(0,p/t2),add(req.gpc0)
# http-request set-var(req.gpc0) sc_get_gpc0(0,p/t3),add(req.gpc0)
# http-request return hdr x-out %[var(req.gpc0)]
bind :::8082 v4v6
default_backend bk_customer
backend bk_customer
mode http
balance roundrobin
log global
http-request track-sc0 srv_conn(bk_customer/haproxy-dest1) table
tracker/quota1
http-request track-sc1 srv_conn(bk_customer/haproxy-dest2) table
tracker/quota2
http-request deny if {
srv_conn(bk_customer/haproxy-dest1),table_gpc0(tracker/quota1) ge 1 }
http-request deny if {
srv_conn(bk_customer/haproxy-dest2),table_gpc1(tracker/quota2) ge 2 }
http-request sc-inc-gpc0(0)
http-request sc-inc-gpc1(0)
server haproxy-dest1 127.0.0.1:8080
server haproxy-dest2 127.0.0.1:8080
peers tracker
#log global
log stdout format raw daemon debug
table quota1 type string size 100 expire 1m store server_id,gpc0
table quota2 type string size 100 expire 1m store server_id,gpc1
bind 127.0.0.1:20001 v4v6
server h2 #alex-TUXEDO-Book-XP1511
server tracker 127.0.0.1:20000 check