5

我正在通过将<img>标签嵌入站点来制作一个高负载的网络统计系统。我想做的是:

  1. nginx 从某个主机获取图像请求
  2. 它给出了从文件系统托管小 1px 静态图像的答案
  3. 此时它以某种方式将请求的标头传输到应用程序并关闭与主机的连接

我正在使用 Ruby,我将制作一个纯机架应用程序来获取标题并将它们放入队列中以进行进一步计算。

我无法解决的问题是,如何配置 sphinx 为 Rack 应用程序提供标头,并返回静态图像作为回复而不等待 Rack 应用程序的响应?

此外,如果有更常见的 Ruby 解决方案,则不需要 Rack。

4

4 回答 4

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 回答
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 回答
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/XSendfileX-Accel-Redirect,这样您就可以将请求转发到您的 ruby​​ 应用程序,然后只需设置响应头,nginx 就会返回文件。

更新,对于 1x1px 透明 GIF 文件,将数据存储在变量中并直接返回给客户端可能更容易(老实说它很小),所以我认为 X-Accel-Redirect 在这种情况下可能是一种矫枉过正。

于 2011-12-19T08:29:33.017 回答