Routing basato su URL in HAProxy: quando serve davvero
Se hai un solo frontend pubblico ma più applicazioni dietro, il routing basato su URL è il modo più pulito per separare traffico, manutenzione e release progressive senza cambiare IP o porte. In pratica, HAProxy decide dove mandare una richiesta osservando elementi della request HTTP: host, path, header, cookie, query string. Il caso più comune è semplice: stesso dominio, percorsi diversi, ad esempio /app, /api, /static. Il punto non è solo “smistare”, ma farlo in modo prevedibile, facile da verificare e soprattutto facile da modificare senza rompere il resto.
La parola chiave qui è adattabile: il routing non deve essere rigido. In produzione cambiano spesso i percorsi reali delle applicazioni, i prefissi dietro reverse proxy, i nomi degli host interni, le esigenze di fallback. Un buon setup HAProxy separa la logica di matching dalla logica di backend, così puoi cambiare una regola senza riscrivere tutto.
Decisione architetturale: host, path o entrambi
Prima di scrivere regole, scegli il criterio di instradamento. Se hai domini distinti, usare Host è più leggibile e meno fragile. Se hai un solo dominio con più servizi, il path routing è la scelta naturale. In ambienti reali spesso conviene combinare le due cose: host per la macro-separazione, path per i servizi sotto lo stesso virtual host.
Un esempio tipico:
- www.example.com verso il frontend web
- www.example.com/api verso il backend API
- admin.example.com verso il pannello amministrativo
- www.example.com/maintenance verso una pagina statica o un backend di emergenza
Questa struttura ti permette di tenere il routing leggibile anche quando il numero di applicazioni cresce. Se invece tenti di mettere tutto in una sola catena di eccezioni, il file di configurazione diventa difficile da mantenere e ogni modifica richiede più attenzione del necessario.
Come HAProxy valuta l’URL
HAProxy lavora con ACL e regole di use_backend. Le ACL sono condizioni booleane; le use_backend dicono quale backend scegliere se la condizione è vera. La logica base è questa: prima definisci le condizioni, poi associ ciascuna condizione a un backend. Il vantaggio è che puoi riusare le stesse ACL in più punti e mantenere il file leggibile.
Per il path routing, le ACL più comuni sono basate su:
pathper il path esattopath_begper il prefissohdr(host)per l’host richiestourl_paramper parametri query, quando serve
La scelta tra path e path_beg non è cosmetica. path matcha solo l’esatto valore, utile per endpoint specifici. path_beg è quello che usi per instradare intere sezioni di sito o applicazione. Se vuoi mandare tutto ciò che inizia con /api a un backend, path_beg /api è la forma corretta.
Esempio minimo leggibile
Questo è un pattern base, adatto a partire senza troppa complessità:
frontend fe_http
bind :80
mode http
acl is_api path_beg /api
acl is_static path_beg /static
acl is_admin hdr(host) -i admin.example.com
use_backend be_api if is_api
use_backend be_static if is_static
use_backend be_admin if is_admin
default_backend be_web
backend be_web
mode http
server web1 10.0.0.10:8080 check
backend be_api
mode http
server api1 10.0.0.20:9000 check
backend be_static
mode http
server static1 10.0.0.30:8080 check
backend be_admin
mode http
server admin1 10.0.0.40:8080 checkQui il comportamento è semplice: prima si controlla se il path è /api, poi /static, poi l’host amministrativo. Se nessuna ACL matcha, si usa il backend di default. Questo ordine conta: le prime regole hanno precedenza pratica quando più condizioni potrebbero essere vere.
Nota operativa: quando usi path routing, verifica sempre che i backend ricevano il path nel formato atteso. Alcune applicazioni si aspettano il prefisso originale, altre vogliono il prefisso rimosso. Se sbagli questo punto, il routing può sembrare corretto ma l’app risponde 404 o genera link rotti.
Riscrittura del path: quando mantenere o togliere il prefisso
Molti problemi nascono qui. Se il tuo frontend è esposto su /app ma il backend applicativo ascolta come se fosse alla root /, devi decidere se trasferire il path così com’è oppure riscriverlo.
Ci sono due modelli:
- Pass-through: il backend vede
/app/loginesattamente come arriva. - Strip prefix: il backend vede
/loginanche se il client ha richiesto/app/login.
Il pass-through è più semplice se l’app supporta un base path configurabile. Lo strip prefix è utile quando l’app non sa di stare dietro un reverse proxy con sottopath. In HAProxy puoi usare regole di rewrite, ma va fatto con attenzione perché una riscrittura errata può alterare redirect, cookie path e asset statici.
Un approccio prudente è testare con una sola route prima di estendere a tutto il traffico. Per esempio, instrada /app verso un backend di staging o verso una versione nuova, osserva i redirect e i link generati, poi estendi la regola.
Routing adattabile con fallback e manutenzione
Il routing “adattabile” non è solo una questione di path. Significa anche poter cambiare comportamento senza toccare il codice applicativo. Due casi concreti:
- Fallback automatico se un backend è giù
- Pagina manutenzione quando vuoi chiudere temporaneamente una sezione
Per il fallback, HAProxy supporta health check e può escludere i server non sani. Se tutti i server di un backend falliscono, puoi inviare il traffico a un backend alternativo o a una pagina statica. Questo è utile per mantenere il servizio parzialmente disponibile durante incidenti o deploy problematici.
Per la manutenzione, spesso conviene avere un backend dedicato, ad esempio una piccola origin che serve una pagina statica. In questo modo puoi deviare solo /api o solo /checkout senza spegnere il sito intero. Se fai e-commerce o servizi transazionali, questa distinzione è importante perché consente di ridurre il blast radius.
Ordine delle regole e collisioni
Quando più ACL possono matchare la stessa request, l’ordine diventa fondamentale. Per esempio, una richiesta a /api/admin può matchare sia path_beg /api sia una regola più specifica per amministrazione. In questi casi devi mettere prima la regola più specifica, oppure creare condizioni esplicite con priorità chiara.
Una buona regola pratica è questa: prima le eccezioni, poi le categorie larghe. Se hai un path speciale come /api/health o /admin/login, non lasciarlo “cadere” dentro una regola generica troppo ampia. Questo evita routing inatteso e semplifica il troubleshooting.
Se vuoi verificare rapidamente la logica, usa richieste sintetiche e osserva l’header o il backend coinvolto. Anche un semplice curl -I può darti segnali utili se aggiungi header di debug lato backend o log di accesso con il nome del server selezionato.
Debug operativo: cosa controllare prima di cambiare la config
Quando il routing non funziona, il primo errore è modificare la config a tentativi. Prima controlla tre cose:
- Il path e l’host arrivano davvero come pensi.
- La regola HAProxy è scritta con il matcher giusto.
- Il backend risponde correttamente se chiamato direttamente.
Per esempio, se una request a /api/v1/users finisce nel backend sbagliato, verifica il path reale con un access log o con una prova diretta:
curl -sv http://frontend.example.com/api/v1/users -o /dev/nullSe hai accesso alla macchina HAProxy, controlla anche la sintassi e lo stato del servizio prima di ricaricare:
haproxy -c -f /etc/haproxy/haproxy.cfg
systemctl status haproxy --no-pagerIl primo comando ti dice se la config è valida. Il secondo ti mostra se il servizio è attivo e se ci sono errori recenti nel journal. Se stai lavorando in produzione, evita reload ciechi: una config valida sintatticamente può comunque avere una logica sbagliata.
Path routing e header rewriting
In molte installazioni il routing URL non basta da solo. Se mandi una richiesta a un backend sotto sottopath, potrebbe essere necessario aggiornare header come X-Forwarded-Proto, X-Forwarded-For e, in alcuni casi, Host. Questo serve all’applicazione per generare link corretti, gestire redirect e costruire URL assoluti.
Se il backend fa redirect verso la root o verso un dominio interno, il problema spesso non è HAProxy che “non instrada”, ma l’app che non è proxy-aware. In quel caso devi verificare se l’app supporta il base URL o se richiede una configurazione specifica. Non risolvere tutto con rewrite aggressivi: rischi di mascherare il problema e introdurre bug più difficili da vedere.
Quando possibile, mantieni coerenti questi elementi:
- URL pubblico esposto al client
- path effettivo ricevuto dall’app
- base URL configurato nell’app
- cookie path e redirect
Se uno di questi quattro punti non coincide, prima o poi avrai 404, loop di redirect o sessioni che sembrano sparire.
Pattern utili per scenari reali
Ci sono alcuni pattern che tornano spesso in produzione. Il primo è il blue/green per path: instradi /app verso il vecchio backend e /app-new verso il nuovo, poi fai switch quando hai verificato che tutto funzioni. Il secondo è il canary per URL specifici: una parte del traffico, o solo alcuni path, va alla nuova versione. Il terzo è il segregation by function: frontend, API, upload, admin, statici separati per ridurre impatti incrociati.
Questi pattern sono semplici, ma funzionano bene perché ti permettono di testare perimetri limitati. Se qualcosa va storto, il rollback è spesso una modifica di pochi byte in config o un cambio di backend target, non un rollback applicativo completo.
Checklist di produzione
Prima di mettere online o modificare il routing, controlla almeno questi punti:
- Le ACL sono ordinate dalla più specifica alla più generale.
- Il backend di default è davvero quello corretto.
- I server backend hanno health check attivi.
- Il path pubblico coincide con il base path dell’app o è riscritto in modo esplicito.
- I redirect non puntano a host interni o a path sbagliati.
- Hai un backup della config prima del reload.
Se lavori con più ambienti, tieni la logica identica tra staging e produzione e cambia solo i target backend. È il modo più veloce per ridurre sorprese.
Consegna operativa: una config semplice batte una config “furba”
La regola pratica è questa: meglio una config leggibile con poche ACL ben nominate che una pipeline di regole troppo intelligente. HAProxy è molto capace, ma la manutenzione quotidiana la farai tu o chi viene dopo di te. Se il routing basato su URL deve durare, deve essere comprensibile in cinque minuti da chi apre il file.
Quando hai bisogno di adattabilità, aggiungi i casi speciali in modo esplicito, non con scorciatoie. Quando hai bisogno di fallback, separa il backend di emergenza da quello normale. Quando hai bisogno di cambiare il base path, verifica l’effetto su redirect, cookie e asset prima di estendere la modifica a tutto il traffico.
Assunzione: esempi pensati per HAProxy in modalità HTTP davanti a backend applicativi Linux standard; i dettagli di rewrite possono cambiare in base alla versione e al comportamento dell’applicazione dietro proxy.
Per approfondire la sintassi ufficiale delle ACL e delle regole di instradamento, la documentazione di HAProxy resta il riferimento primario: docs.haproxy.org.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.