2011-12-21 10 views
19

2つのiKaaroインスタンスが9080インスタンスが読み取り専用のポート8080と9080で動作しています。リクエストメソッドがPOSTかPUTかDELETEかに基づくnginx proxy_pass

たとえば、リクエストメソッドがPOST、PUT、DELETEの場合は、インスタンス(8080)に送信し、9080インスタンスに送信する場合は、nginxの使い方が不明です。

私は正規表現を使って場所を使って何かをしましたが、これは正しくありません。私はあなたが得たと仮定し

location ~* "(ngx.HTTP_POST|ngx.HTTP_DELETE|ngx.HTTP_PUT)" { 
    proxy_pass http://127.0.0.1:8080; 

おかげ

+0

質問を少し良く説明できますか?あなたはその設定を試しましたか?あなたはそれに何か誤りがありますか? – kikito

答えて

33

私はちょうど簡単なテストをした、これは私の仕事:単にリクエストメソッドによって条件を作るための方法を探している場合、誰かに

server { 
    location/{ 
    # This proxy_pass is used for requests that don't 
    # match the limit_except 
    proxy_pass http://127.0.0.1:8080; 

    # For requests that *aren't* a PUT, POST, or DELETE, 
    # pass to :9080 
    limit_except PUT POST DELETE { 
     proxy_pass http://127.0.0.1:9080; 
    } 
    } 
} 
+1

これはさらに短くなっています – khinester

+1

また、サードパーティのモジュールに依存していません – kolbyjack

+2

nginx 1.7.6 .. –

10

を:http://wiki.nginx.org/HttpLuaModuleから

私はそれが正しいと場所のブロックを追加することで、呼び出すことができる「HTTPメソッド定数」があることを見ます場所の基礎。 I.E.あなたのサーバーにLua 5.1をインストールしているか、LuaJIT 2.0をインストールして、ngx_luaモジュールを使ってNginxをコンパイルし、必要に応じてngx_luaを設定しました。代わりにそれと

は、これが仕事をする:私はあなたが特に大きな範囲でのLuaを使用していたかもしれないと思っ

location /test { 
    content_by_lua ' 
     local reqType = ngx.var.request_method 
     if reqType == ngx.HTTP_POST 
      OR reqType == ngx.HTTP_DELETE 
      OR reqType == ngx.HTTP_PUT 
     then 
      res = ngx.location.capture("/write_instance") 
     else 
      res = ngx.location.capture("/read_instance") 
     end 
     ngx.say(res.body) 
    '; 
} 
location /write_instance { 
    internal; 
    proxy_pass http://127.0.0.1:8080; 
} 
location /read_instance { 
    internal; 
    proxy_pass http://127.0.0.1:9080; 
} 

UPDATE。以下の例は、limit_exceptと同じ原則でも動作します。

location /test { 
    if ($request_method !~* GET) { 
     # For Write Requests 
     proxy_pass http://127.0.0.1:8080; 
    } 
    # For Read Requests 
    proxy_pass http://127.0.0.1:9080; 
} 

「IF」と「limit_except」ブロック効果的にネストされた位置のブロックを作成して、条件が一致した後、このようにして作成内側位置ブロックの唯一のコンテンツハンドラ(「proxy_pass」)が実行される両方。

ifが "悪"と言われることもありますが、この場合、 "if"と "limit_except"の両方に共通の "悪"の振る舞いが、まさにあなたが望むものかもしれません。

3つの選択肢から選ぶことができます!

ただし、他のディレクティブを設定する必要がある場合は、 "if"または "limit_except"オプションのいずれかを使用して "悪"の動作で噛まないように注意しなければなりません。

I.E. "if"または "limit_except"ブロック内でディレクティブを設定した場合、ディレクティブはその外側でアクティブでなく、同様に外部に設定されたものが内部で継承される可能性があります。場合によっては、どちらの方法でも、どのようにデフォルトが継承されるかを監視する必要があります。

If is Evilページに記載されているすべての潜在的な問題は、ここでは「if」と「limit_except」に等しく適用されます。 Luaベースのスクリプティング手法は、そのページで提案されているような潜在的な落とし穴の多くを回避します。

幸運を祈る!

+0

これは感謝していただきありがとうございます。 – khinester

+0

詳細な説明のおかげで、IfiSEvilが他の指令を実行する必要があるかどうかを気にする必要があります。 ロケーション〜* "(ログイン| new_content)"などの特定のURLも含める必要があるので、必要になるかもしれません。... ...しかし、私はそれを理解して、ここでnginx.confファイルで改善することができる。 – khinester

+0

特定の問題でクエリを区切ります。私は、あなたが持っている3つのオプションで、Nginxの要求メソッドに基づいたルート要求がどのように徹底的に答えられたかに関する特定の質問を仮定します。潜在的な問題を念頭に置いたif文の一種である「直接」または「limit_except」を使用するか、これらの問題を回避するために与えられたLuaの例のようなスクリプト方法を使用できます。あなたは与えられた答えのいずれかを受け入れ、他の問題がある場合には新しい質問をすることを検討したいかもしれません。 – Dayo

1

、構文は次のとおりです。

if ($request_method = DELETE) { 
    . . . 
} 
+1

で動作しません。 nginxチーム:http://wiki.nginx.org/IfIsEvil – Sych

1

私は、nginxマップ関数をお勧めしたいと思います。これはあなたの場所のブロックの外に行く:

map $request_method $destination { 
    default 8080; 
    PUT 9080; 
    POST 9080; 
    DELETE 9080; 
} 

そして、お住まいの地域ブロックに:

map $request_method $cookie_auth $destination { 
    default 8080; 
    "^POST " 9080; 
    "^PUT someAuthCookieValue" 9080; 
} 

プラスこの:あなたのようなことを行うことができますので

proxy_pass http://127.0.0.1:$destination 

これは、あまりにもすべての正規表現ですifの使用をまったく避けます。それはかなり素晴らしいです。私はWordPressクラスタ内のすべての書き込みトラフィックをリモートノード上の1つのFastCGI TCPソケットに送信するのに使用しましたが、ローカルのFastCGI UNIXソケットに読み取りトラフィックを送信しました。

関連する問題