
У меня есть несколько служб, работающих на разных портах, каждая из которых использует одни и те же пути URI. Например:
New York Housing Service
127.0.0.1:8080/homes
127.0.0.1:8080/prices
Las Vegas Housing Service
127.0.0.1:8081/homes
127.0.0.1:8081/prices
До сих пор все было хорошо, но теперь мне нужно настроить haproxy для балансировки нагрузки сервисов. Таким образом, мне, очевидно, нужно иметь возможность различать их для переключения контента. Я представляю, что я бы добавил параметр к пути в ACL, чтобы различать два бэкэнда, в этом случае, имея параметр url в ACL, за которым следовали бы фактические параметры пути для приложения:
frontend http
maxconn 2000
bind 0.0.0.0:5000
acl new-york path_reg -i /newyork.*
use_backend nyc-server if new-york
acl las-vegas path_reg -i /lasvegas.*
use_backend lv-server if las-vegas
backend nyc-server
server www.test.com 127.0.0.1:8080 maxconn 100
backend lv-server
server www.test.com 127.0.0.1:8081 maxconn 100
В этой настройке переход по адресу 127.0.0.1:5000/newyork/home перенесет меня на 127.0.0.1:8080/home, а 127.0.0.1:5000/lasvegas/home переносит меня на 127.0.0.1:8081/home. Мои попытки до сих пор просто возвращали ошибку 404. Я просматривал документацию, но не нашел ничего, что соответствовало бы моему варианту использования, поэтому любая помощь будет принята с благодарностью.
EDIT: Я забыл упомянуть, что я использую haproxy 1.5.18
решение1
Службы бэкенда отвечают ошибками HTTP 404, поскольку ваша конфигурация HAPROXY в настоящее время пересылает путь URL-адреса как есть. Например, запрос HTTP для http://127.0.0.1:5000/newyork/home/wtc.png
пересылается на nyc-server
бэкенд как http://127.0.0.1:8000/newyork/home/wtc.png
.
$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 13:00:09-- http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 404 File not found
2020-02-01 13:00:09 ERROR 404: File not found.
$ python -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
127.0.0.1 - - [01/Feb/2020 13:00:09] code 404, message File not found
127.0.0.1 - - [01/Feb/2020 13:00:09] "GET /newyork/homes/wtc.png HTTP/1.1" 404 -
HAproxy должен быть настроен на перевод путей URL-адресов путем удаления первого компонента пути при извлечении ресурсов из бэкендов. Я бы посоветовал вам добавить reqrep
директиву в определение фронтенда, которая должна манипулировать первой строкой заголовка HTTP-запроса и переводить что-то вроде GET /newyork/homes/wtc.png HTTP/1.1
в GET /homes/wtc.png HTTP/1.1
.
frontend http
reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$ \1\ \2
Однако это не сработает, поскольку HAproxy оценивает reqrep
директивы раньше use-backend
, тем самым нарушая внутреннюю оценку:
$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 13:54:55-- http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 503 Service Unavailable
2020-02-01 13:54:55 ERROR 503: Service Unavailable.
Вторым рабочим подходом является переписывание URL-пути в определениях бэкенда. Однако, в зависимости от количества бэкендов в обслуживании, написание reqrep
директив и настройка каждого бэкенда для выполнения перезаписи URL подвержены ошибкам.
backend nyc-server
server www.test.com 127.0.0.1:8080 maxconn 100
reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$ \1\ \2
backend lv-server
server www.test.com 127.0.0.1:8081 maxconn 100
reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$ \1\ \2
$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 14:02:29-- http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 456892 (446K) [image/png]
Saving to: ‘/dev/null’
/dev/null 100%[===============>] 446.18K --.-KB/s in 0s
2020-02-01 14:02:29 (1.83 GB/s) - ‘/dev/null’ saved [456892/456892]
$ python -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
127.0.0.1 - - [01/Feb/2020 14:02:29] "GET /homes/wtc.png HTTP/1.1" 200 -