MEDIUM: proxy: mark the "dispatch" directive as deprecated

As mentioned in [1], the "dispatch" directive from haproxy 1.0 has long
outlived its original purpose and still suffers from a number of technical
limitations (no checks, no SSL, no idle connes etc) and still hinders some
internal evolutions. It's now time to mark it as deprecated, and to remove
it in 3.5 [2]. It was already recommended against in the documentation but
remained popular in raw TCP environments for being shorter to write.

The directive will now cause a warning to be emitted, suggesting an
alternate method involving "server". The warning can be shut using
"expose-deprecated-directives". The rare configs from 1.0 where
"dispatch" is combined with sticky servers using cookies will just
need to set these servers's weights to zero to prevent them from
being selected by the load balancing algorithm. All of this is
explained in the doc with examples.

Two reg tests were using this method, one purposely for this directive,
which now has expose-deprecated-directives, and another one to test the
behavior of idle connections, which was updated to use "server" and
extended to test both "http-reuse never" and "http-reuse always".

[1] https://github.com/orgs/haproxy/discussions/2921
[2] https://github.com/haproxy/wiki/wiki/Breaking-changes
This commit is contained in:
Willy Tarreau 2025-06-26 15:29:47 +02:00
parent 19140ca666
commit 5c15ba5eff
4 changed files with 110 additions and 8 deletions

View File

@ -5474,7 +5474,7 @@ default-server X - X X
default_backend X X X -
description - X X X
disabled X X X X
dispatch - - X X
dispatch (deprecated) - - X X
email-alert from X X X X
email-alert level X X X X
email-alert mailers X X X X
@ -6818,7 +6818,7 @@ disabled
See also : "enabled"
dispatch <address>:<port>
dispatch <address>:<port> (deprecated)
Set a default server address
May be used in the following contexts: tcp, http
@ -6842,6 +6842,27 @@ dispatch <address>:<port>
syntax, it has also been used for simple TCP relays. It is recommended not to
use it for more clarity, and to use the "server" directive instead.
This keyword has been deprecated in 3.3 and will be removed in 3.5 due to
some internal limitations (no support for SSL nor idle connections etc).
Using it will emit a warning that may be silenced by enabling directive
"expose-deprecated-directives" in the global section.
The correct way to proceed without this directive is to simply declare a
server with the same address and port. If the "dispatch" directive was
mixed with other servers, then these servers should be configured with a
weight of zero in order never to be elected by the load balancing algorithm.
Example:
backend deprecated_setup
dispatch 192.168.100.100:80 # external load balancer's address
server s1 192.168.100.1:80 cookie S1 check
server s2 192.168.100.2:80 cookie S2 check
backend modern_setup
server external_lb 192.168.100.100:80
server s1 192.168.100.1:80 cookie S1 check weight 0
server s2 192.168.100.2:80 cookie S2 check weight 0
See also : "server"

View File

@ -12,6 +12,10 @@ server s2 {
} -start
haproxy h1 -conf {
global
# this is needed since 3.3, and this test will be removed in 3.5.
expose-deprecated-directives
defaults
log global
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"

View File

@ -7,16 +7,26 @@ varnishtest "Test the proper interaction between http-reuse and dispatch mode"
feature ignore_unknown_macro
haproxy h1 -conf {
global
nbthread 1
defaults
timeout client 30s
timeout server 30s
timeout connect 30s
mode http
listen sender
bind "fd@${feS}"
listen sender1
bind "fd@${feN}"
http-reuse never
http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found }
dispatch ${h1_feR_addr}:${h1_feR_port}
server dispatch ${h1_feR_addr}:${h1_feR_port}
listen sender2
bind "fd@${feA}"
http-reuse always
http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found }
server dispatch ${h1_feR_addr}:${h1_feR_port}
listen receiver
bind "fd@${feR}"
@ -26,7 +36,8 @@ haproxy h1 -conf {
http-after-response set-header client-id %[var(sess.client_id)]
} -start
client c1 -connect ${h1_feS_sock} {
### http-reuse never
client c1 -connect ${h1_feN_sock} {
txreq \
-hdr "client-id: c1"
rxresp
@ -43,7 +54,7 @@ client c1 -connect ${h1_feS_sock} {
expect resp.http.client-id == "c1"
} -run
client c2 -connect ${h1_feS_sock} {
client c2 -connect ${h1_feN_sock} {
txreq \
-hdr "client-id: c2"
rxresp
@ -61,7 +72,7 @@ client c2 -connect ${h1_feS_sock} {
expect resp.http.client-id == "c2"
} -run
client c3 -connect ${h1_feS_sock} {
client c3 -connect ${h1_feN_sock} {
txreq \
-hdr "client-id: c3"
rxresp
@ -78,3 +89,57 @@ client c3 -connect ${h1_feS_sock} {
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c3"
} -run
### http-reuse always
client c4 -connect ${h1_feA_sock} {
txreq \
-hdr "client-id: c4"
rxresp
expect resp.http.http_first_request == "1"
txreq
rxresp
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c4"
txreq
rxresp
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c4"
} -run
client c5 -connect ${h1_feA_sock} {
txreq \
-hdr "client-id: c5"
rxresp
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c5"
txreq
rxresp
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c5"
txreq
rxresp
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c5"
} -run
client c6 -connect ${h1_feA_sock} {
txreq \
-hdr "client-id: c6"
rxresp
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c6"
txreq
rxresp
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c6"
txreq
rxresp
expect resp.http.http_first_request == "0"
expect resp.http.client-id == "c6"
} -run

View File

@ -2664,6 +2664,18 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
if (alertif_too_many_args(1, file, linenum, args, &err_code))
goto out;
if (!deprecated_directives_allowed) {
ha_warning("parsing [%s:%d]: '%s' is deprecated in 3.3 and will be removed in 3.5. "
"The modern way to do the same is to create a server with the same address, and "
"possibly to assign any extra server a weight of zero if any:\n"
" server dispatch %s\n"
"Note that it is still possible to silence this warning by setting "
"'expose-deprecated-directives' in the 'global' section, but do not wait to fix "
"your configuration!\n",
file, linenum, args[0], args[1]);
err_code |= ERR_WARN;
}
curproxy->dispatch_addr = *sk;
curproxy->options |= PR_O_DISPATCH;
}