Haproxy route и переписать на основе URI-пути
Я пытаюсь настроить Haproxy для загрузки запросов баланса на несколько бэкендов, идентифицированных по пути uri. Например:
https://www.example.com/v1/catalog/foo/bar
Должно привести к созданию "каталога-v1".
Каждое приложение реагирует на другой путь, поэтому я должен не только идентифицировать приложение, но и переписывать URL-адрес. Например.
К
Я знаю, что я не должен использовать Haproxy для перезаписи, но на данный момент это неизбежно.
Пробовал следующее регулярное выражение, которое работало над regex101:
([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*)
Замена:
\1/\3-\2/\4
И, наконец, haproxy.config:
global
daemon
user root
group root
maxconn 256000
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
stats socket /run/haproxy/stats.sock mode 777 level admin
defaults
log global
option dontlognull
maxconn 4000
retries 3
timeout connect 5s
timeout client 1m
timeout server 1m
option redispatch
balance roundrobin
listen stats :8088
mode http
stats enable
stats uri /haproxy
stats refresh 5s
backend catalog-v1
mode http
option httpchk GET /catalog-v1/ping
http-check expect status 200
reqrep ([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*) \1/\3-\2/\4
server 127.0.0.1:8280_catalog-v1-node01 127.0.0.1:8280 check inter 2s rise 3 fall 2
backend checkout-v1
mode http
option httpchk GET /checkout-v1/ping
http-check expect status 200
reqrep ([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*) \1/\3-\2/\4
server 127.0.0.1:8180_checkout-v1-node01 127.0.0.1:8180 check inter 2s rise 3 fall 2
frontend shared-frontend
mode http
bind localhost:80
acl is-catalog-v1-path path_dir /v1/catalog
acl is-checkout-v1-path path_dir /v1/checkout
use_backend catalog-v1 if is-catalog-v1-path
use_backend checkout-v1 if is-checkout-v1-path
Я что-то пропустил?
Я боролся с этим довольно долгое время без успеха. Бэкэнды показывают "UP" на странице Haproxy stats, но каждый раз, когда я вызываю "непереписанный URL", я получаю ошибку 400 Bad Request.
Заранее благодарим за помощь!
Ответы
Ответ 1
Если вы правильно поняли, замените приведенный ниже пример:
reqrep ^([^\ ]\*)\ /([-.0-9A-Za-z]\*)/([a-zA-Z]\*)/(.\*) \1\ /\3-\2/\4
http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#reqrep
reqrep search string [{if | unless} cond]
У вас нет пробелов.
Ответ 2
Ответ выше - это одно исправление, которое не объясняет корень проблемы. Проблема в том, что многие предполагают, что мы анализируем полный URL-адрес или только компонент PATH, когда мы на самом деле разбираем/переписываем HTTP-заголовки.
Например:
curl -iv https://stackoverflow.com/info/24784517/haproxy-route-and-rewrite-based-on-uri-path
* Trying 151.101.65.69...
> GET /info/24784517/haproxy-route-and-rewrite-based-on-uri-path HTTP/1.1
> Host: stackoverflow.com
> User-Agent: curl/7.54.0
> Accept: */*
Цель состоит в том, чтобы переписать GET /some_path HTTP/1.1
в GET /some_other_path HTTP/1.1
Я хочу пояснить, что приведенное выше решение работает, потому что оно учитывает HTTP-глагол в матче и заменяет. ^([^\ ]\*)\ (.*)
, чтобы захватить глагол и использовать его в шаблоне замены. \1 \2