2014-07-16 9 views
12

Sto tentando di impostare un Haproxy per caricare le richieste di bilanciamento su alcuni backend identificati dal percorso uri. Per esempio:Haproxy route e riscrittura basata sul percorso URI

https://www.example.com/v1/catalog/foo/bar

dovrebbe portare alla backend "Catalogo-v1".

A questo punto ogni app risponde su un percorso diverso, quindi non devo solo identificare l'app ma riscrivere il percorso dell'URL. Per esempio.

PER

So che non dovrei usare per scopi HAProxy riscrittura, ma per ora questo è inevitabile.

provato la seguente espressione regolare che ha lavorato su regex101:

([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*) 

Sostituzione:

\1/\3-\2/\4 

E infine ecco la 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 

Mi sto perdendo qualcosa?

Ho lottato con questo per un po 'di tempo senza successo. I backend mostrano "UP" nella pagina delle statistiche di Haproxy ma ogni volta che chiamo "url non riscritto" ottengo un errore di 400 Bad Request.

Grazie in anticipo per il vostro aiuto!

risposta

9

Se ho capito bene, sostituire il seguente esempio:

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] 

Non ci sono spazi.

+0

Ha funzionato perfettamente! Credo di aver perso qualcosa. Grazie! – leovrf

+0

Ho avuto difficoltà con uno simile. In pratica, desidero reindirizzare l'URL example.com/test/app/v1/foo/bar -> otherexample.com/v1/app/foo/bar. Ho provato a usare regex 'reqrep^([^ \] *) \/([a-zA-Z] \ *)/([a-zA-Z] \ *)/([0-9A- Za-z] \ *)/(. *) \ 1 \/\ 4/\ 3/\ 5' con la configurazione del server come 'nome server otherexample.com check maxqueue 200 weight 100' – user320550

1

La risposta sopra è una singola correzione che non spiega la radice del problema. Il problema è che molti pensano che stiamo analizzando un URL completo o solo il componente PATH, quando in realtà stiamo analizzando/riscrivendo le intestazioni HTTP.

Ad esempio:

curl -iv https://stackoverflow.com/questions/24784517/haproxy-route-and-rewrite-based-on-uri-path 
* Trying 151.101.65.69... 
> GET /questions/24784517/haproxy-route-and-rewrite-based-on-uri-path HTTP/1.1 
> Host: stackoverflow.com 
> User-Agent: curl/7.54.0 
> Accept: */* 

L'obiettivo è quello di riscrivere GET /some_path HTTP/1.1-GET /some_other_path HTTP/1.1

Ci tengo a precisare che la soluzione sopra funziona perché prende in considerazione il verbo HTTP nella partita e sostituire. ^([^\ ]\*)\ (.*) per acquisire il verbo e utilizzarlo nel modello di sostituzione. \1 \2