5

<img>サイトにタグを埋め込むことで負荷の高いWeb統計システムを作っています。私がやりたいことは次のとおりです。

  1. nginx は、ホストからイメージのリクエストを取得します
  2. ファイルシステムから小さな1pxの静止画像をホストするための答えとして与えます
  3. この時点で、何らかの方法でリクエストのヘッダーをアプリケーションに転送し、ホストへの接続を閉じます

私は Ruby で作業しており、純粋なラック アプリを作成してヘッダーを取得し、さらに計算するためにそれらをキューに入れます。

私が解決できない問題は、Sphinx を設定して Rack アプリにヘッダーを渡し、Rack アプリケーションからの応答を待たずに応答として静止画像を返すにはどうすればよいですか?

また、より一般的な Ruby ソリューションがあれば、Rack は必要ありません。

4

4 に答える 4

2

ここでpost_actionについて読み、「NginxからPOSTを介して静的コンテンツを提供する」を読んだ後http://invalidlogic.com/2011/04/12/serving-static-content-via-post-from-nginx/ 私はこれを使用してこれを達成しました:

server {
  # this is to serve a 200.txt static file 
  listen 8888;
  root /usr/share/nginx/html/;
}
server {
  listen 8999;
  location / {
    rewrite ^ /200.txt break;
  }

  error_page 405 =200 @405;
  location @405 {
    # post_action, after this, do @post
    post_action @post;
    # this nginx serving a static file 200.txt
    proxy_method GET;
    proxy_pass http://127.0.0.1:8888;
  }

  location @post {
    # this will go to an apache-backend server.
    # it will take a long time to process this request
    proxy_method POST;
    proxy_pass http://127.0.0.1/$request_uri;
  }
}
于 2012-01-26T00:45:22.537 に答える
2

簡単なオプションは、バックエンド プロセスを続行しながらクライアント接続をできるだけ早く終了することです。

server {
    location /test {
        # map 402 error to backend named location
        error_page 402 = @backend;

        # pass request to backend
        return 402;
    }

    location @backend {
        # close client connection after 1 second
        # Not bothering with sending gif
        send_timeout 1;

        # Pass the request to the backend.
        proxy_pass http://127.0.0.1:8080;
    }
}

上記のオプションは単純ですが、接続が切断されたときにクライアントがエラー メッセージを受け取る可能性があります。ngx.say ディレクティブは、"200 OK" ヘッダーが送信されることを保証し、これは非同期呼び出しであるため、処理が遅れることはありません。これには ngx_lua モジュールが必要です。

server {
    location /test {
        content_by_lua '
            -- send a dot to the user and transfer request to backend
            -- ngx.say is an async call so processing continues after without waiting
            ngx.say(".")
            res = ngx.location.capture("/backend")

        ';
    }

    location /backend {
        # named locations not allowed for ngx.location.capture
        # needs "internal" if not to be public
        internal;

        # Pass the request to the backend.
        proxy_pass http://127.0.0.1:8080;
    }

}

より簡潔な Lua ベースのオプション:

server {
    location /test {
        rewrite_by_lua '
            -- send a dot to the user
            ngx.say(".")

            -- exit rewrite_by_lua and continue the normal event loop
            ngx.exit(ngx.OK)
        ';
        proxy_pass http://127.0.0.1:8080;
    }
}

間違いなく興味深い挑戦です。

于 2011-12-18T19:07:51.513 に答える
1

post_actionでこれを達成できるかもしれません(これがうまくいくかどうかは完全にはわかりませんが、私が考えることができるのはそれだけです)

server {
  location / {
    post_action @post;
    rewrite ^ /1px.gif break;
  }

  location @post {
    # Pass the request to the backend.
    proxy_pass http://backend$request_uri;

    # Using $request_uri with the proxy_pass will preserve the original request,
    # if you use (fastcgi|scgi|uwsgi)_pass, this would need to be changed.
    # I believe the original headers will automatically be preserved.
  }
}
于 2011-12-04T18:43:01.860 に答える
0

http://wiki.nginx.org/XSendfileを利用しないのはなぜですかX-Accel-Redirect。そうすれば、リクエストを Ruby アプリに転送し、レスポンス ヘッダーを設定するだけで、nginx がファイルを返すことができます。

Update、まあ 1x1px 透明 GIF ファイルの場合、データを変数に格納してクライアントに直接返す方がおそらく簡単です (正直なところ、それほど小さいです)。この場合、X-Accel-Redirect はおそらくやり過ぎだと思います。

于 2011-12-19T08:29:33.017 に答える