Skip to content

Commit e0da4fe

Browse files
adamoveranmelehan
andauthored
[NEW] Getting Started with HAProxy Part 2: HTTP Load Balancing (#7095)
* Getting Started with HAProxy Part 2: HTTP Load Balancing * Tech Edit 1 * Tech Edit 2 * Tech Edit 3 * Tech Edit 4 * Copy edits --------- Co-authored-by: Nathan Melehan <[email protected]>
1 parent 42269b9 commit e0da4fe

File tree

5 files changed

+298
-0
lines changed

5 files changed

+298
-0
lines changed
282 KB
Loading
204 KB
Loading
61.4 KB
Loading
39.5 KB
Loading
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
---
2+
slug: how-to-configure-haproxy-http-load-balancing-and-health-checks
3+
title: "How to Configure HAProxy HTTP Load Balancing and Health Checks"
4+
description: "Learn how to configure HAProxy for HTTP load balancing, with instructions on updating frontend and backend settings, path-based routing, and health checks."
5+
authors: ["Tom Henderson"]
6+
contributors: ["Tom Henderson"]
7+
published: 2024-09-18
8+
keywords: ['haproxy','http load balancing','http health checks','haproxy acl']
9+
license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)'
10+
---
11+
12+
[HAProxy](http://www.haproxy.org) is an intermediary gateway application that manages traffic between frontend clients and backend server resources. HAProxy can be configured to load balance traffic between a set of backend servers, and it can be configured to route HTTP requests according to the URL path of the request.
13+
14+
This guide is the second part in a series on HAProxy. The first guide, [Getting Started with HAProxy TCP Load Balancing and Health Checks](/docs/guides/getting-started-with-haproxy-tcp-load-balancing-and-health-checks/), provided steps to build a minimally configured network of Nanodes:
15+
16+
- An HAProxy node was set up as a TCP load balancer
17+
- Three Linode Marketplace WordPress servers served as the backends
18+
- TCP health checks were configured on the HAProxy node
19+
20+
This second guide presents another configuration for this server cluster that demonstrates how to use path-based routing and HTTP health checks.
21+
22+
## Before You Begin
23+
24+
Follow the [Before You Begin](/docs/guides/getting-started-with-haproxy-tcp-load-balancing-and-health-checks/#before-you-begin) and [Install HAProxy](/docs/guides/getting-started-with-haproxy-tcp-load-balancing-and-health-checks/#install-haproxy) sections of the [Getting Started with HAProxy TCP Load Balancing and Health Checks](/docs/guides/getting-started-with-haproxy-tcp-load-balancing-and-health-checks/) guide.
25+
26+
{{< note >}}
27+
This guide is written for a non-root user. Commands that require elevated privileges are prefixed with `sudo`. If you’re not familiar with the `sudo` command, see the [Users and Groups](/docs/guides/linux-users-and-groups/) guide.
28+
{{< /note >}}
29+
30+
## HTTP Path-based Routing
31+
32+
By using the `acl` and `use_backend` directives, HAProxy can direct URL requests to specific backend servers based on the incoming HTTP request string.
33+
34+
### The `acl` Directive
35+
36+
An [*ACL* (Access Control List)](https://www.haproxy.com/documentation/haproxy-configuration-tutorials/core-concepts/acls/#acl-syntax) directive can be used to match a specific URL path. The syntax for an ACL is:
37+
38+
```file {title="/etc/haproxy/haproxy.conf"}
39+
acl {{< placeholder "ACL_NAME" >}} {{< placeholder "ACL_FETCH" >}} {{< placeholder "ACL_URL_MATCH_STRING" >}}
40+
```
41+
42+
An ACL *fetch* method is used to retrieve information from the HTTP request. The `path` fetch method gets the URL for the request. For example, this directive is named `match_foo` and evaluates to true if the URL path for the request is `/foo`:
43+
44+
```file {title="/etc/haproxy/haproxy.conf"}
45+
acl match_foo path /foo
46+
```
47+
48+
There are [variants of the `path` method](https://docs.haproxy.org/2.4/configuration.html#7.3.6-path) that provide similar functionality. For example, `path_beg` checks that the beginning of the path matches the URL string provided. As well, there are fetch methods for other request information, like the source IP of the address or any URL parameters that were present.
49+
50+
When you define an ACL, you specify a unique name for it. That name is later referenced in your configuration (demonstrated in the next [`use_backend` Directive](#the-use_backend-directive) section) to direct requests to specific backends.
51+
52+
### The `use_backend` Directive
53+
54+
A `use_backend` HAProxy directive routes requests to specific backend servers. This directive references a previously-declared `acl` directive by the unique name associated with it. If that ACL evaluated to true for the request, then the request is routed to that specific backend. The syntax for this is:
55+
56+
```file {title="/etc/haproxy/haproxy.conf"}
57+
use_backend {{< placeholder "BACKEND_NAME" >}} if {{< placeholder "ACL_NAME" >}}
58+
```
59+
60+
### Path-based Routing Example
61+
62+
To demonstrate how path-based routing works in practice, follow these steps for the HAProxy and WordPress cluster:
63+
64+
1. Edit the HAProxy configuration to include this `frontend` section:
65+
66+
```file {title="/etc/haproxy/haproxy.cfg"}
67+
frontend http
68+
bind *:80
69+
mode http
70+
acl sample-page path_beg /index.php/sample-page/
71+
acl author-archive path_beg /index.php/author/admin/
72+
use_backend backend1 if sample-page
73+
use_backend backend2 if author-archive
74+
default_backend mybackend
75+
```
76+
77+
Here's an explanation for each line:
78+
79+
- `frontend http`: Defines a frontend named `http` that handles incoming HTTP connections.
80+
- `bind *:80`: Binds the frontend to all available IP addresses on port `80`, listening for incoming traffic.
81+
- `mode http`: Sets the mode to HTTP, allowing traffic to be processed at the application layer.
82+
- `acl sample-page path_beg /index.php/sample-page/`: Defines an ACL named `sample-page` to match requests starting with `/index.php/sample-page/`.
83+
- `acl author-archive path_beg /index.php/author/admin/`: Defines an ACL named `author-archive` to match requests starting with `/index.php/author/admin/`.
84+
- `use_backend backend1 if sample-page`: Routes requests to `backend1` if the `sample-page` ACL is matched.
85+
- `use_backend backend2 if author-archive`: Routes requests to `backend2` if the `author-archive` ACL is matched.
86+
- `default_backend mybackend`: Routes all other requests to the default backend, `mybackend`, if no ACL matches.
87+
88+
1. The HAProxy configuration must also include two additional `backend` sections. These direct incoming frontend requests to the correct backend server. Update the configuration file to include these sections. Replace the placeholder IP addresses with the addresses from the WordPress servers:
89+
90+
```file {title="/etc/haproxy/haproxy.cfg"}
91+
backend mybackend
92+
mode http
93+
balance roundrobin
94+
server backend1 {{< placeholder "backend1_VLAN_IP_ADDRESS" >}}:80
95+
server backend2 {{< placeholder "backend2_VLAN_IP_ADDRESS" >}}:80
96+
server backend3 {{< placeholder "backend3_VLAN_IP_ADDRESS" >}}:80
97+
98+
backend backend1
99+
mode http
100+
server backend1 {{< placeholder "backend1_VLAN_IP_ADDRESS" >}}:80
101+
102+
backend backend2
103+
mode http
104+
server backend2 {{< placeholder "backend2_VLAN_IP_ADDRESS" >}}:80
105+
```
106+
107+
Here's an explanation of each line:
108+
109+
- `backend mybackend`: Defines a backend pool called `mybackend` that handles client requests directed to it.
110+
- `mode http`: Sets the backend mode to HTTP, processing traffic at the application layer.
111+
- `balance roundrobin`: Distributes incoming requests evenly across the servers in the `mybackend` pool.
112+
- `server backend1/backend2/backend3`: Lists three servers (`backend1`, `backend2`, `backend3`) in the `mybackend` pool, each assigned their respective VLAN IP addresses and listening on port `80`.
113+
- `backend backend1`: Defines an individual backend for `backend1`, allowing specific configuration.
114+
- `server backend1`: Adds `backend1` with its VLAN IP address and port `80` to this backend.
115+
- `backend backend2`: Defines an individual backend for `backend2`, similar to the setup for `backend1`.
116+
- `server backend2`: Adds `backend2` with its VLAN IP address and port `80`.
117+
118+
## HTTP Health Checks
119+
120+
In [Getting Started with HAProxy TCP Load Balancing and Health Checks](/docs/guides/getting-started-with-haproxy-tcp-load-balancing-and-health-checks/), the HAProxy gateway was configured to test TCP and Layer 4 connectivity, marking servers as down when errors accumulate over time. HTTP health checks work similarly, but use standard HTTP response codes to mark servers as "down" based on their performance over a specified interval.
121+
122+
Like TCP health checks, HTTP health checks continue to test a server marked as "down" to see if it begins to respond. If it starts responding correctly, the server is added back to the pool of active servers.
123+
124+
You can also configure HTTP health checks to look for specific values rather than standard HTTP response codes. This can be done using *REGEX* (regular expressions) or simple text matches within the first 16 KB of the backend server's response. For example, a string could match phrases like "Alive" or "Logged In" within a session.
125+
126+
### Basic HTTP Health Checks
127+
128+
Like with TCP health checks, adding the `check` directive to the `server` lines within the `backend` section of your HAProxy configuration file monitors the health of backend servers. However, this is only a TCP health check. In order to activate an HTTP health check, you also need to add the `option httpchk` to the `backend` section.
129+
130+
To demonstrate this with the example HAProxy and WordPress cluster, add these new directives to the `backend mybackend` section of your HAProxy configuration:
131+
132+
```file {title="/etc/haproxy/haproxy.cfg"}
133+
backend mybackend
134+
option httpchk
135+
server backend1 {{< placeholder "backend1_IP_ADDRESS" >}}:80 check
136+
server backend2 {{< placeholder "backend2_IP_ADDRESS" >}}:80 check
137+
server backend3 {{< placeholder "backend3_IP_ADDRESS" >}}:80 check
138+
```
139+
140+
- `check`: Appending this keyword to each `server` entry activates the health check on that server.
141+
- `option httpchk`: Adding this option allows HAProxy to perform HTTP health checks. By default, standard responses from the server in the `200`-`399` range indicate that the server is healthy. Meanwhile, responses in the `500` range mark the server as down and remove it from the active pool until it recovers.
142+
143+
{{< note >}}
144+
By default, the `option httpchk` directive sends a `GET` request to the `/` endpoint to determine server health. However, this can be customized for a specific endpoint, such as `/health`:
145+
146+
```file {title="/etc/haproxy/haproxy.cfg"}
147+
backend mybackend
148+
option httpchk GET /health
149+
```
150+
{{< /note >}}
151+
152+
### String-based HTTP Health Checks
153+
154+
With the `http-check expect string` directive, HTTP health checks can also query and match specific strings in the backend server's responses. However, only the first 64 KB of the response is examined. If headers are lengthy or include large elements like inline graphics, the desired string may not be within this limit, and it is then missed by the health check.
155+
156+
To demonstrate this with the example HAProxy and WordPress cluster, add this new directive to the `backend mybackend` section of your HAProxy configuration:
157+
158+
```file {title="/etc/haproxy/haproxy.cfg"}
159+
backend mybackend
160+
option httpchk
161+
http-check expect string OK
162+
server backend1 {{< placeholder "backend1_IP_ADDRESS" >}}:80 check
163+
server backend2 {{< placeholder "backend2_IP_ADDRESS" >}}:80 check
164+
server backend3 {{< placeholder "backend3_IP_ADDRESS" >}}:80 check
165+
```
166+
167+
- `http-check`: This directive checks a server response three times before marking the server as "down". The code above configures HAProxy to check that a response was returned the string `OK`. You can adjust this string to match any other server response that indicates a healthy state.
168+
169+
### The HAProxy Stats Page
170+
171+
HTTP health checks offer a more approachable way to monitor the health of your servers than TCP health checks. While HTTP health checks can still be viewed from log files, they can also be viewed from HAProxy's web-based graphical stats page.
172+
173+
Enable the stats page by adding a `listen` section to the HAProxy configuration file::
174+
175+
```file {title="/etc/haproxy/haproxy.cfg"}
176+
listen stats
177+
bind *:8404
178+
mode http
179+
stats enable
180+
stats uri /stats
181+
stats refresh 10s
182+
stats auth admin:password # Set a username and password for access
183+
```
184+
185+
- `listen` creates a new listen section named `stats`.
186+
- `bind` tells HAProxy to listen on all available network interfaces (`8`) on port `8404`.
187+
- `mode` is set to HTTP.
188+
- `stats enable` enables the stats function.
189+
- `stat uri/stats` defines the URL where the stats page can be accessed (`http://{{< placeholder "HAProxy_IP_ADDRESS" >}}:8404/stats`)
190+
- `stats refresh 10s` sets the auto-refresh interval at 10 seconds.
191+
- `stats auth admin:password` configures basic credentials for the stats page. Replace `admin` and `password` with the username and password of your choice.
192+
193+
## Test HTTP Load Balancing with Health Checks
194+
195+
Follow these steps to test the concepts from the previous sections:
196+
197+
1. After including all of the directives described in the previous sections, your HAProxy configuration should now resemble the following. Verify that your configuration matches this:
198+
199+
```file {title="/etc/haproxy/haproxy.cfg"}
200+
listen stats
201+
bind *:8404
202+
mode http
203+
stats enable
204+
stats uri /stats
205+
stats refresh 10s
206+
stats auth admin:password # Set a username and password for access
207+
208+
frontend http
209+
bind *:80
210+
mode http
211+
acl sample-page path_beg /index.php/sample-page/
212+
acl author-archive path_beg /index.php/author/admin/
213+
use_backend backend1 if sample-page
214+
use_backend backend2 if author-archive
215+
default_backend mybackend
216+
217+
backend mybackend
218+
mode http
219+
balance roundrobin
220+
option httpchk
221+
server backend1 {{< placeholder "backend1_VLAN_IP_ADDRESS" >}}:80 check
222+
server backend2 {{< placeholder "backend2_VLAN_IP_ADDRESS" >}}:80 check
223+
server backend3 {{< placeholder "backend3_VLAN_IP_ADDRESS" >}}:80 check
224+
225+
backend backend1
226+
mode http
227+
option httpchk
228+
server backend1 {{< placeholder "backend1_VLAN_IP_ADDRESS" >}}:80 check
229+
230+
backend backend2
231+
mode http
232+
option httpchk
233+
server backend2 {{< placeholder "backend2_VLAN_IP_ADDRESS" >}}:80 check
234+
```
235+
236+
1. Reload HAProxy for the changes to take effect:
237+
238+
```command
239+
sudo systemctl reload haproxy
240+
```
241+
242+
{{< note >}}
243+
If you encounter any errors after reloading HAProxy, run the following command to check for syntax errors in your `haproxy.cfg` file:
244+
245+
```command
246+
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
247+
```
248+
249+
An error message is returned if the configuration file has logical or syntax errors. When the check is complete, each error is listed one per line. This command only verifies the syntax and basic logic of the configuration, it does not guarantee that the configuration works as intended when running.
250+
{{< /note >}}
251+
252+
1. Open a web browser and access the HAProxy server’s IP address:
253+
254+
```command
255+
http://{{< placeholder "HAPROXY_SERVER_IP_ADDRESS" >}}
256+
```
257+
258+
{{< note >}}
259+
If your browser warns of no HTTPS/TLS certificate, ignore the warning or use the advanced settings to reach the site.
260+
{{< /note >}}
261+
262+
This page is served by the `mybackend` pool that consists of all three WordPress instances:
263+
264+
![The 2024 default WordPress homepage served from backend1.](2024-Default-WordPress-Homepage-backend1.png)
265+
266+
1. Open the default WordPress Sample Page:
267+
268+
```command
269+
http://{{< placeholder "HAPROXY_SERVER_IP_ADDRESS" >}}/index.php/sample-page/
270+
```
271+
272+
This URL should only be served by `backend1`:
273+
274+
![The 2024 default WordPress Sample Page served from backend1.](WordPress-Sample-Page-backend1.png)
275+
276+
1. Navigate to the default WordPress author archive for `admin`:
277+
278+
```command
279+
http://{{< placeholder "HAPROXY_SERVER_IP_ADDRESS" >}}/index.php/author/admin/
280+
```
281+
282+
This URL should only be served by `backend2`:
283+
284+
![The 2024 default WordPress admin Author Archive served from backend2.](WordPress-admin-Author-Archive-backend2.png)
285+
286+
1. Open a web browser and navigate the HAProxy server's public IP address with `:8404/stats` appended to the URL:
287+
288+
```command
289+
http://{{< placeholder "HAPROXY_SERVER_IP_ADDRESS">}}:8404/stats
290+
```
291+
292+
1. When prompted, enter your username and password from the `listen` section of the HAProxy configuration file.
293+
294+
1. You should now see the HAProxy stats page showing `mybackend`, `backend1`, and `backend2`:
295+
296+
![The HAProxy stats page showing all three defined backends.](HAProxy-stats-page.png)
297+
298+
This page holds a wealth of information regarding the health of your servers, including status, sessions, bytes in/out, errors, warnings, and more.

0 commit comments

Comments
 (0)