Skip to content

Commit 3ef29b4

Browse files
committed
MINOR: haload: import source code and documentation
This patch imports the implementation of haload, a lightweight, multi-threaded traffic generator designed to benchmark HTTP infrastructures under heavy loads. Built onto HAProxy's highly scalable architecture, it natively supports HTTP/1, HTTP/2, and HTTP/3 (QUIC). It uses the previously exposed initialization functions, the no-listener mode, the lightweight hbuf API, and the specialized hldstream object types to dynamically derive and generate its configuration in memory from basic command-line inputs. By leveraging HAProxy's internal HTX (Internal HTTP Native Representation) format, haload abstractly manipulates HTTP elements independently of the wire protocol. This abstraction allows it to generate unified requests and process responses seamlessly across HTTP/1.1, HTTP/2, or HTTP/3 without duplicating the payload handling logic for each version. - Makefile: Introduce the 'haload' compilation target and define HALOAD_OBJS. - src/haload.c, include/haproxy/haload.h: Add user and stream task scheduling handlers, HTX-driven traffic orchestration mechanisms, and terminal benchmarking statistical summary rendering. - src/haload_init.c: Implement program arguments parsing, fileless HAProxy memory configuration generation, and target URL allocations. - src/stconn.c: Wire up sc_attach_mux() to properly allocate the specific tasklet context when dealing with a haload stream. - doc/haload.txt: Add detailed documentation covering compilation, flags, and usage examples.
1 parent 330d600 commit 3ef29b4

7 files changed

Lines changed: 2813 additions & 0 deletions

File tree

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,7 @@ endif # TARGET
902902
903903
OBJS =
904904
HATERM_OBJS =
905+
HALOAD_OBJS =
905906
906907
ifneq ($(EXTRA_OBJS),)
907908
OBJS += $(EXTRA_OBJS)
@@ -957,6 +958,8 @@ endif
957958
958959
HATERM_OBJS += $(OBJS) src/haterm_init.o src/hbuf.o
959960
961+
HALOAD_OBJS += $(OBJS) src/haload_init.o src/haload.o src/hbuf.o
962+
960963
# Used only for forced dependency checking. May be cleared during development.
961964
INCLUDES = $(wildcard include/*/*.h)
962965
DEP = $(INCLUDES) .build_opts
@@ -1007,6 +1010,9 @@ haproxy: $(OPTIONS_OBJS) $(OBJS)
10071010
haterm: $(OPTIONS_OBJS) $(HATERM_OBJS)
10081011
$(cmd_LD) $(ARCH_FLAGS) $(LDFLAGS) -o $@ $^ $(LDOPTS)
10091012
1013+
haload: $(OPTIONS_OBJS) $(HALOAD_OBJS)
1014+
$(cmd_LD) $(ARCH_FLAGS) $(LDFLAGS) -o $@ $^ $(LDOPTS)
1015+
10101016
objsize: haproxy
10111017
$(Q)objdump -t $^|grep ' g '|grep -F '.text'|awk '{print $$5 FS $$6}'|sort
10121018

doc/haload.txt

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
------
2+
HALoad
3+
------
4+
HAProxy's dummy HTTP
5+
client for benchmarks
6+
7+
1. Background
8+
-------------
9+
10+
HALoad is a lightweight, multi-threaded traffic generator designed to benchmark
11+
HTTP infrastructures under heavy loads. Built directly onto HAProxy's highly
12+
scalable core architecture, it shares its parent engine's efficient handling of
13+
connections. This framework allows the tool to generate high-volume traffic
14+
across all standard application layers, including HTTP/1, HTTP/2, and HTTP/3
15+
(QUIC), over either cleartext or secured TLS connections.
16+
17+
The primary design goal is to provide a modernized alternative to legacy tools
18+
like h1load, extending benchmarking capabilities to newer protocols. Notably,
19+
HALoad introduces the concept of users (-u), a feature completely absent
20+
from h1load. Here, a "user" strictly represents an independent, concurrent
21+
HTTP client task. Under this architecture, each simulated client will
22+
instantiate as many backend server connections as there are target URLs
23+
specified on the command line.
24+
25+
HALoad does not require any configuration file. Instead, the configuration is
26+
dynamically derived from basic command line inputs. This ensures immediate
27+
usability for test operators while retaining the ability to test complex,
28+
multi-protocol setups.
29+
30+
31+
2. Compilation
32+
--------------
33+
34+
The compilation process mirrors standard HAProxy builds, specifying "haload"
35+
as the compilation target via the command line:
36+
37+
$ make -j $(nproc) TARGET=linux-glibc haload
38+
39+
To enable encrypted communication layers (TLS/SSL):
40+
41+
$ make TARGET=linux-glibc USE_OPENSSL=1 haload
42+
43+
For advanced HTTP/3 over QUIC load testing:
44+
45+
$ make -j $(nproc) TARGET=linux-glibc USE_OPENSSL=1 USE_QUIC=1 haload
46+
47+
Because HALoad shares the code of the main HAProxy binary, it natively
48+
inherits all standard HAProxy compiler flags, optimizations, and build
49+
targets.
50+
51+
52+
3. Execution
53+
------------
54+
55+
HALoad displays its usage when run without argument or wrong arguments:
56+
57+
Usage : haload [opts] [URL]
58+
where <opts> may be any combination of:
59+
-d <time> test duration in seconds (0)
60+
-e stop upon first connection error
61+
-h(0|1|2|2c|3) use h0 (hq-interop for QUIC), h1, h2, h2c or h3
62+
(QUIC/TCP) protocols (*)
63+
-(0|1|2|2c|3) same as above (*)
64+
-l enable long output format; double for raw values
65+
-m <streams> maximum concurrent streams (1)
66+
-n <reqs> maximum total requests (-1)
67+
-r <reqs> number of requests per connection (-1)
68+
-s <time> soft start: time in sec to reach 100% load
69+
-t <threads> number of threads
70+
-u <users> number of users (1)
71+
-w <time> I/O timeout in milliseconds (10000)
72+
-C dump the configuration and exit
73+
-H "foo:bar" add this header name and value
74+
-I use HEAD instead of GET
75+
-v shows version
76+
--defaults <str> add a string to default section
77+
--global <str> add a string to global section
78+
--server <opts> set server <opt> options as defined for "server"
79+
haproxy keyword
80+
--show-status-codes show HTTP status codes distribution
81+
--traces enable the traces for all the HTTP protocols
82+
SSL options:
83+
--tls-ciphers <ciphers> for TLS1.2 and below (*)
84+
--tls-ciphersuites <ciphers> for TLS1.3 and above (*)
85+
--tls-curves <curves> (*)
86+
URL format:
87+
(http://|https://|quic://)<addr>:<port>/<path>
88+
Note: Options marked with an asterisk (*) are positional and MUST be placed
89+
BEFORE the URLs they are intended to affect.
90+
91+
92+
At startup, HALoad dynamically generates an HAProxy configuration in memory.
93+
Options like --global and --defaults allow raw configuration lines to be added
94+
directly to the "global" and "defaults" sections, while --server appends
95+
options to the backend server. These parameters support standard escaped
96+
notation (e.g., '\n' or '\t') to insert multi-line statements in a single
97+
argument en ligne de commande.
98+
99+
100+
Examples:
101+
102+
# 30-second test using 4 threads simulating 10 distinct users
103+
$ ./haload -t 4 -u 10 -d 30 http://127.0.0.1:8888/
104+
105+
# HTTP/3 test limiting concurrent streams to 3 per connection (-m3)
106+
$ ./haload -m3 quic://127.0.0.1:8889/
107+
108+
# Dump the generated memory configuration and exit (-C)
109+
$ ./haload https://127.0.0.1:4443 -C
110+
global
111+
tune.memory.hot-size 3145728
112+
ssl-server-verify none
113+
tune.h2.be.max-concurrent-streams 1
114+
tune.quic.be.stream.max-concurrent 1
115+
116+
# Dump the configuration and exit (-C) to check -m3 effect
117+
$ ./haload https://127.0.0.1:4443 -m3 -C
118+
global
119+
tune.memory.hot-size 3145728
120+
ssl-server-verify none
121+
tune.h2.be.max-concurrent-streams 3
122+
tune.quic.be.stream.max-concurrent 3
123+
124+
# Add a custom directive into defaults, dump the configuration and exit (-C)
125+
$ ./haload https://127.0.0.1:4443 --defaults "timeout connect 5s" -C
126+
global
127+
tune.memory.hot-size 3145728
128+
ssl-server-verify none
129+
tune.h2.be.max-concurrent-streams 1
130+
tune.quic.be.stream.max-concurrent 1
131+
defaults
132+
timeout connect 5s
133+
134+
135+
4. Limitations
136+
--------------
137+
138+
When using HTTP/3 (QUIC or QMUX) protocols with the maximum concurrent streams
139+
option (-m) enabled, HAProxy's connection layer currently does not enforce or
140+
respect the strict limit on the number of open connections usually dictated by
141+
the concurrent users option (-u).
142+
143+
For example, when targeting a single URL, specifying "-u 10 -m 5" might lead
144+
to opening more than 10 concurrent connections to the target server under
145+
heavy load, instead of strictly capping the total connections to the requested
146+
number of users.

include/haproxy/haload.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#ifndef _HAPROXY_HALOAD_H
2+
#define _HAPROXY_HALOAD_H
3+
4+
#include <import/ist.h>
5+
#include <haproxy/list-t.h>
6+
#include <haproxy/proxy-t.h>
7+
#include <haproxy/server-t.h>
8+
#include <haproxy/task-t.h>
9+
10+
struct hld_path {
11+
char *path;
12+
struct hld_path *next;
13+
};
14+
15+
struct hld_url_cfg {
16+
int ssl;
17+
int is_quic;
18+
int h2c;
19+
char *addr;
20+
char *raw_addr; // used only to set the host header value
21+
char *srv_opts;
22+
char *tls_opts;
23+
char *alpn;
24+
struct server *srv;
25+
struct hld_path *paths;
26+
struct hld_path *cur_path;
27+
struct hld_url_cfg *next;
28+
};
29+
30+
struct hld_url {
31+
int mreqs;
32+
int flags;
33+
uint64_t tot_req;
34+
uint64_t tot_rconn_done;
35+
uint64_t tot_rconn_sent;
36+
struct hld_url_cfg *cfg;
37+
struct hld_url *next;
38+
};
39+
40+
/* haload header */
41+
struct hld_hdr {
42+
struct ist name;
43+
struct ist value;
44+
struct list list;
45+
};
46+
47+
extern const char *arg_host;
48+
extern const char *arg_conn_hdr;
49+
extern const char *arg_uri;
50+
extern const char *arg_path; // TO REMOVE
51+
extern struct list hld_hdrs;
52+
extern struct hld_url_cfg *hld_url_cfgs;
53+
54+
extern struct proxy hld_proxy;
55+
extern int arg_accu;
56+
extern int arg_dura;
57+
extern int arg_fast;
58+
extern int arg_head;
59+
extern int arg_hscd;
60+
extern int arg_long;
61+
extern int arg_mreqs;
62+
extern int arg_reqs;
63+
extern int arg_rcon;
64+
extern int arg_slow;
65+
extern int arg_serr;
66+
extern int arg_usr;
67+
extern int arg_thrd;
68+
extern int arg_wait;
69+
70+
#endif /* _HAPROXY_HALOAD_H */

include/haproxy/hldstream-t.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
struct hldstream {
1313
enum obj_type obj_type;
1414
struct connection *conn;
15+
unsigned int expire;
1516
int64_t hash;
1617
struct hld_usr *usr;
1718
struct hld_url *url;
@@ -23,6 +24,7 @@ struct hldstream {
2324
int flags;
2425
int state;
2526
unsigned long long to_send; /* number of body data bytes to send */
27+
struct timeval req_date;
2628
struct list list;
2729
};
2830

0 commit comments

Comments
 (0)