On 09.12.22 13:17, Aleksandar Lazic wrote:
Hi.
As I still think that the Balancing algorithm (Peak) EWMA (
https://github.com/haproxy/haproxy/issues/1570 ) could help to make a
"better" decision to which server should the request be send, here the
beginning of the patches.
In any cases it would be nice to know the rtt from the backend, Imho.
Does anybody know how I can "delay/sleep/wait" for the server answer to
get some rtt which are not 0 as the rtt is 0.
Here the updated Patch without the EWMA reference.
Regards
Alex
From 7610bb7234bd324e06e56732a67bf8a0e65d7dbc Mon Sep 17 00:00:00 2001
From: Aleksandar Lazic <al-hapr...@none.at>
Date: Fri, 9 Dec 2022 13:05:52 +0100
Subject: [PATCH] MINOR: sample: Add bc_rtt and bc_rttvar
This Patch adds the fetch sample for backends round trip time.
---
doc/configuration.txt | 16 ++++++++++
reg-tests/sample_fetches/tcpinfo_rtt.vtc | 39 ++++++++++++++++++++++++
src/tcp_sample.c | 33 ++++++++++++++++++++
3 files changed, 88 insertions(+)
create mode 100644 reg-tests/sample_fetches/tcpinfo_rtt.vtc
diff --git a/doc/configuration.txt b/doc/configuration.txt
index c45f0b4b6..e8526de7f 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -18854,6 +18854,22 @@ be_server_timeout : integer
current backend. This timeout can be overwritten by a "set-timeout" rule. See
also the "cur_server_timeout".
+bc_rtt(<unit>) : integer
+ Returns the Round Trip Time (RTT) measured by the kernel for the backend
+ connection. <unit> is facultative, by default the unit is milliseconds. <unit>
+ can be set to "ms" for milliseconds or "us" for microseconds. If the server
+ connection is not established, if the connection is not TCP or if the
+ operating system does not support TCP_INFO, for example Linux kernels before
+ 2.4, the sample fetch fails.
+
+bc_rttvar(<unit>) : integer
+ Returns the Round Trip Time (RTT) variance measured by the kernel for the
+ backend connection. <unit> is facultative, by default the unit is milliseconds.
+ <unit> can be set to "ms" for milliseconds or "us" for microseconds. If the
+ server connection is not established, if the connection is not TCP or if the
+ operating system does not support TCP_INFO, for example Linux kernels before
+ 2.4, the sample fetch fails.
+
be_tunnel_timeout : integer
Returns the configuration value in millisecond for the tunnel timeout of the
current backend. This timeout can be overwritten by a "set-timeout" rule. See
diff --git a/reg-tests/sample_fetches/tcpinfo_rtt.vtc b/reg-tests/sample_fetches/tcpinfo_rtt.vtc
new file mode 100644
index 000000000..f28a2072e
--- /dev/null
+++ b/reg-tests/sample_fetches/tcpinfo_rtt.vtc
@@ -0,0 +1,39 @@
+varnishtest "Test declaration of TCP rtt fetches"
+
+# feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(v2.8-dev1)'"
+feature ignore_unknown_macro
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+haproxy h1 -conf {
+ defaults common
+ mode http
+ timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+
+ frontend fe from common
+ bind "fd@${feh1}"
+
+ default_backend be
+
+ backend be from common
+
+ http-response set-header x-test1 "%[fc_rtt]"
+ http-response set-header x-test2 "%[bc_rtt]"
+ http-response set-header x-test3 "%[fc_rttvar]"
+ http-response set-header x-test4 "%[bc_rttvar]"
+
+ server s1 ${s1_addr}:${s1_port}
+
+} -start
+
+client c1 -connect ${h1_feh1_sock} {
+ txreq -req GET -url /
+ rxresp
+ expect resp.status == 200
+ #expect resp.http.x-test2 ~ " ms"
+} -run
diff --git a/src/tcp_sample.c b/src/tcp_sample.c
index 925b93291..bf0d538ea 100644
--- a/src/tcp_sample.c
+++ b/src/tcp_sample.c
@@ -373,6 +373,34 @@ static inline int get_tcp_info(const struct arg *args, struct sample *smp,
return 1;
}
+/* get the mean rtt of a backend/server connection */
+static int
+smp_fetch_bc_rtt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+ if (!get_tcp_info(args, smp, 1, 0))
+ return 0;
+
+ /* By default or if explicitly specified, convert rtt to ms */
+ if (!args || args[0].type == ARGT_STOP || args[0].data.sint == TIME_UNIT_MS)
+ smp->data.u.sint = (smp->data.u.sint + 500) / 1000;
+
+ return 1;
+}
+
+/* get the variance of the mean rtt of a backend/server connection */
+static int
+smp_fetch_bc_rttvar(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+ if (!get_tcp_info(args, smp, 1, 1))
+ return 0;
+
+ /* By default or if explicitly specified, convert rttvar to ms */
+ if (!args || args[0].type == ARGT_STOP || args[0].data.sint == TIME_UNIT_MS)
+ smp->data.u.sint = (smp->data.u.sint + 500) / 1000;
+
+ return 1;
+}
+
/* get the mean rtt of a client connection */
static int
smp_fetch_fc_rtt(const struct arg *args, struct sample *smp, const char *kw, void *private)
@@ -479,6 +507,11 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
{ "bc_src", smp_fetch_src, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV },
{ "bc_src_port", smp_fetch_sport, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV },
+#ifdef TCP_INFO
+ { "bc_rtt", smp_fetch_bc_rtt, ARG1(0,STR), val_fc_time_value, SMP_T_SINT, SMP_USE_L4CLI },
+ { "bc_rttvar", smp_fetch_bc_rttvar, ARG1(0,STR), val_fc_time_value, SMP_T_SINT, SMP_USE_L4CLI },
+#endif
+
{ "dst", smp_fetch_dst, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI },
{ "dst_is_local", smp_fetch_dst_is_local, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI },
{ "dst_port", smp_fetch_dport, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI },
--
2.34.1