HAProxy – Necessidade de adicionar um parâmetro de URL à ACL para diferenciar entre serviços com a mesma URL, mas em portas diferentes

HAProxy – Necessidade de adicionar um parâmetro de URL à ACL para diferenciar entre serviços com a mesma URL, mas em portas diferentes

Tenho vários serviços executados em portas diferentes, cada uma usando os mesmos caminhos de URI. Por exemplo:

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

Até agora tudo bem, mas agora preciso configurar o haproxy para balancear a carga dos serviços. Como tal, obviamente preciso ser capaz de diferenciá-los para a troca de conteúdo. O que imagino que faria é adicionar um parâmetro ao caminho na ACL para diferenciar entre os dois backends, neste caso tendo um parâmetro url na ACL, que seria seguido pelos parâmetros reais do caminho para a aplicação:


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

Nesta configuração, ir para 127.0.0.1:5000/newyork/home me levará para 127.0.0.1:8080/home, enquanto 127.0.0.1:5000/lasvegas/home me leva para 127.0.0.1:8081/lar. Minhas tentativas até agora simplesmente retornaram um erro 404. Estive examinando a documentação, mas não vi nada que corresponda ao meu caso de uso, portanto, qualquer ajuda seria muito apreciada.

EDIT: esqueci de mencionar que estou usando o haproxy 1.5.18

Responder1

Os serviços de back-end estão respondendo com erros HTTP 404 porque sua configuração HAPROXY está encaminhando o caminho do URL como está. Por exemplo, uma solicitação HTTP http://127.0.0.1:5000/newyork/home/wtc.pngestá sendo encaminhada para nyc-serverback-end como 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 -

O HAproxy deve ser configurado para traduzir caminhos de URLs removendo o primeiro componente de caminho enquanto busca recursos de back-ends. Eu sugiro que você adicione uma reqrep diretiva na definição do frontend, que visa manipular a primeira linha do cabeçalho da solicitação HTTP e traduzir algo como GET /newyork/homes/wtc.png HTTP/1.1into GET /homes/wtc.png HTTP/1.1.

frontend http
  reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$  \1\ \2

No entanto, não funcionará porque o HAproxy avalia reqrepas diretivas antes use-backenddas outras, quebrando assim a avaliação de back-end:

$ 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.

Uma segunda abordagem de trabalho é reescrever o caminho da URL nas definições de back-end. No entanto, dependendo do número de back-ends em serviço, escrever reqrepdiretivas e configurar cada back-end para executar a reescrita de URL está sujeito a erros.

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 -

informação relacionada