Простое перенаправление на серверы HAproxy
Я хочу настроить простое перенаправление с HAproxy.
Желаемое поведение: HAProxy получает запрос к example.com или https://example.com/ и возвращает стартовую страницу веб-сервера https из списка серверов, исключая себя из цепочки. Я пробовал с redirect location https://web1.com code 301 if example_acl
и это работает для одного сервера, но мне нужно 5 серверов за редиректом, с web1.com, web2.com... и циклическим перебором. Может быть, есть какой-то конкретный конфиг для бэкэнда? пожалуйста помоги
Мой текущий конфиг
-#------------------- GLOBAL SETTINGS ---------------------------
...
-#------------------- FRONTEND HTTP ---------------------------
frontend http_in
mode http
option httplog
bind *:80
stats enable
redirect scheme https if { hdr(Host) -i example.com }
-#------------------- FRONTEND TCP ---------------------------
frontend tcp_in
mode tcp
option tcplog
bind *:443
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
acl example_acl req.ssl_sni -i example.com
use_backend special_example if example_acl
-#------------------- Server Farms ---------------------------
backend special_example
mode tcp
balance roundrobin
?
1 ответ
Я согласен с комментатором, это выглядит как необычное приложение, но, тем не менее, HAProxy проходит.
Я создал запись файла hosts на моем тестовом прокси, так что example.com фактически указывает на 127.0.0.1, поэтому тесты, приведенные ниже, являются реальными ответами от прокси.
Допустим, я хочу example.com
перенаправить на один из четырех серверов, external-1.example.com
через external-4.example.com
,
Это однострочник - все для удобства показано на одной строке.
Это идет в frontend
раздел.
http-request redirect code 301
location http://external-%[rand(4),add(1)].%[req.hdr(host)]%[url]
if { req.hdr(host) -m str example.com }
{ req.hdr(host) -m str example.com }
является анонимным ACL, который позволяет перенаправление if
это соответствует текущему запросу. location
использует rand(n)
выборка выборки, которая генерирует случайное число от 0 до n-1; за ним следует (передает его значение) add(x)
преобразователь, который добавляет x к значению - в этом случае мы берем возможные значения от 0 до (4 - 1) включительно и добавляем 1, так что %[rand(4),add(1)]
Выражение выражается числом от 1 до 4 включительно, которое неявно приводится к строке. Мы объединяем http://external-
с этим целым числом, точкой, заголовком входящего хоста %[req.hdr(host)]
и URL %[url]
, который включает в себя путь и строку запроса.
Тест 1:
$ curl -v http://example.com
* Rebuilt URL to: http://example.com/
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to example.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: example.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Content-length: 0
< Location: http://external-4.example.com/
< Connection: close
Тест 2:
< HTTP/1.1 301 Moved Permanently
< Content-length: 0
< Location: http://external-2.example.com/
< Connection: close
Да, это работает.
Если бы вам нужно было перенаправить на набор имен хостов, которые не были последовательно пронумерованы, решение было бы аналогичным, но вы бы использовали http-request set-var
чтобы сохранить случайное число в переменной транзакции, затем серию операторов перенаправления, по одному для каждого хоста, каждый из которых имеет свой собственный анонимный ACL, который будет оценивать случайное значение на равенство целому числу, совпадающему с этим хостом, и перенаправлять, если переменная содержал это значение.
rand()
fetch не является генератором случайных чисел криптографического качества, но, безусловно, кажется достаточным для этого варианта использования.