2015-08-13 15 views
6

Ho un server nginx con config per usare queryparam come hash upstream. URL assomiglia sottocome utilizzare il percorso url come hash upstream in nginx

http://www.my-server.com/xyz/WXYZ?abc=123 

e la configurazione, come di seguito

upstream test { 
    hash $arg_abc; 
    .... 
} 

v'è alcuna possibilità di utilizzare WXYZ parte di URL, hash a monte?

WXYZ è il valore dinamico e xyz è sempre lo stesso e ci sarà.

questo è quello che ho provato,

location ~ ^/xyz/(.).*$ { 
    hash $1 
} 
+0

Hai risolto il problema? – Anatoly

risposta

6

The deployment guide esplicitamente dicono che è possibile:

Il metodo hash generico: il server a cui viene inviato è determinato da una chiave definita dall'utente una richiesta che può essere un testo, una variabile o la loro combinazione . Ad esempio, la chiave può essere una fonte IP e la porta, o URI:

upstream backend { 
    hash $request_uri consistent; 

    server backend1.example.com; 
    server backend2.example.com; 
} 

La chiave hash viene $ REQUEST_URI che possono essere sostituiti con $ arg_your_key ma non è sicuro è opere con a monte blocco, tuttavia dovrebbe funzionare valore come proxy_pass:

location /xyz { 
    proxy_pass http://localhost/$uri$is_args$args; 
} 

Non sono sicuro di requisiti, ma se avete bisogno di usare certa backend basato sulla tesi $ arg_abc avete bisogno della funzione mappare, come here:

map $arg_abc $backend_server { 
default 'serverdefault.domain.com:80'; 
123 'server1.domain.com:80'; 
234 'server2.domain.com:80'; 
345 'server3.domain.com:80'; 
} 

server { 
location/{ 
    proxy_pass http://$backend_server; 
} 
} 
2

Sì, secondo la documentazione per hash, è possibile utilizzare solo nel upstream contesto, così che cosa hai provato non funziona davvero.

Tuttavia, perché è esattamente necessario utilizzare solo un determinato percorso dall'URI, invece del tutto, se le altre parti rimangono uguali? Penso che l'idea sia che l'intera stringa dovrebbe essere ulteriormente hash, quindi, anche se tutti i tuoi URL iniziano lo stesso, la funzione hash dovrebbe comunque distribuire tutto in modo uniforme. Quindi, molto probabilmente è sufficiente usare $request_uri o $uri come hash.

In alternativa, se si vuole ancora fare a modo tuo, si potrebbe tentare di utilizzare il pattern matching chiamato nel vostro location (location ~ ^/xyz/(?<varForHash>.).*$ {…), e quindi utilizzare le variabili da tali partite ($varForHash) come hash (si potrebbe forse anche utilizzare $1 anche dal proprio esempio, nel giusto contesto — upstream).

+0

Puoi pubblicare del codice per la seconda via. Sono un po 'confuso su ciò che sto facendo male secondo il tuo secondo esempio – Exception

+0

stai avendo la direttiva 'hash' all'interno di' location', mentre dovrebbe essere all'interno del contesto 'upstream'; spostalo da 'location' a' upstream', che potrebbe funzionare; ma anche se fosse così, sarebbe molto meglio usare "capture nominate" come sopra. – cnst

1

ho ottenuto compito simile e ho risolto. Ho creato upstream.conf e l'ho aggiunto a nginx.conf. Il contenuto di upstream.conf è qui sotto:

map $uri $myvar{ 
    default $uri; 
    # pattern "Method1" + "/" + GUID + "/" + target parameter + "/" + HASH; 
    "~*/Method1/(.*)/(.*)/(.*)$" $2; 
    # pattern "Method2" + "/" + GUID + "/" + target parameter; 
    "~*/Method2/(.*)/(.*)$" $2; 
} 


upstream backend { 
    hash $myvar consistent; 
    server s1:80; 
    server s2:80; 
} 
Problemi correlati