2015-08-13 7 views
6

verwenden Ich habe einen Nginx-Server mit Config, um Abfrageparam als Upstream-Hash zu verwenden. URL sieht aus wie untenWie URL Pfadname als Upstream-Hash in Nginx

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

und Konfiguration wie unter

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

ist es eine Möglichkeit, WXYZ Teil der URL als Upstream-Hash zu benutzen?

WXYZ ist dynamischer Wert und xyz ist immer gleich und wird da sein.

das ist, was ich versuchte,

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

Haben Sie das Problem gelöst? – Anatoly

Antwort

6

The deployment guide explizit gesagt, es ist möglich:

Die generische Hash-Methode: der Server an die eine Anfrage gesendet wird, wird von einem benutzerdefinierten Schlüssel bestimmt wird, die ein Text, variabel sein kann, oder deren Kombination . Zum Beispiel kann der Schlüssel eine Quell-IP und Port sein, oder URI:

upstream backend { 
    hash $request_uri consistent; 

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

Der Hash-Schlüssel wird $ request_uri, die mit $ arg_your_key ersetzt werden kann, aber nicht sicher ist, arbeitet mit vorgeschaltetem Block, aber es sollte als proxy_pass Wert arbeiten:

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

Nicht Anforderungen sicher, aber wenn Sie benötigen bestimmte Backend auf Basis von Argumente $ arg_abc Sie benötigen Funktionskarte, wie 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

Ja, gemäß der Dokumentation für hash, können Sie es nur im upstream Kontext verwenden, also, was Sie haben versucht, nicht wirklich funktionieren.

Allerdings, warum genau brauchen Sie nur einen bestimmten Pfad von Ihrem URI, anstatt der ganzen Sache, wenn diese anderen Teile sowieso gleich bleiben? Ich denke, die Idee ist, dass die gesamte Zeichenfolge sowieso weiter gehasht werden soll. Selbst wenn alle URLs gleich beginnen, sollte die Hash-Funktion dennoch alles gleichmäßig verteilen. Sie können also höchstwahrscheinlich einfach $request_uri oder $uri als Hash verwenden.

Alternativ, wenn Sie es noch Ihren Weg machen wollen, können Sie versuchen, genannt Pattern-Matching in Ihrem location (location ~ ^/xyz/(?<varForHash>.).*$ {…) zu verwenden, und dann die Variablen aus diesen Begegnungen verwenden ($varForHash) als hash (Sie könnten wahrscheinlich sogar Verwenden Sie auch $1 aus Ihrem Beispiel, nur im richtigen Kontext — upstream).

+0

Kannst du Code für den zweiten Weg posten? Ich bin ein wenig verwirrt hier auf, was ich falsch mache, wie in Ihrem zweiten Beispiel – Exception

+0

Sie haben 'Hash' Direktive innerhalb' location', während es im 'upstream' Kontext sein sollte; verschiebe es einfach von 'location' nach' upstream', was funktionieren könnte; Aber selbst wenn dies der Fall ist, wäre es eine viel bessere Idee, "benannte Aufnahmen" wie oben zu verwenden. – cnst

1

ich ähnliche Aufgabe, und ich löste es. Ich habe upstream.conf erstellt und zur nginx.conf hinzugefügt. Der Inhalt der upstream.conf ist unten:

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; 
}