基于请求方法是POST、PUT或DELETE的nginx代理传递。

我有两个运行在端口8080和9080上的iKaaro实例,其中9080实例是只读的。

我不确定如何使用nginx,例如如果请求方法为POST、PUT、DELETE,则发送到写入实例(8080),否则发送到9080实例。

我使用了location和正则表达式做了一些东西,但这是不正确的。

http://wiki.nginx.org/HttpLuaModule中我看到有'HTTP方法常量'可以调用,所以是否正确在location块中添加:

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

原文链接 https://stackoverflow.com/questions/8591600

点赞
stackoverflow用户891636
stackoverflow用户891636

我假设你已经了解了基础知识。例如,你在服务器上安装了 Lua 5.1,或者更好的是,安装了 LuaJIT 2.0,编译了带有 ngx_lua 模块的 Nginx,并按要求配置了 ngx_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;
}

更新

我认为也许你是在更大的范围内使用 Lua。下面的示例也可以使用与 limit_except 相同的原理。

location /test {
    if ($request_method !~* GET) {
        # 对于写入请求
        proxy_pass http://127.0.0.1:8080;
    }
    # 对于读取请求
    proxy_pass http://127.0.0.1:9080;
}

“if” 和 “limit_except”的块都有效地创建一个嵌套的位置块。一旦条件匹配,只有所创建的内部位置块的内容处理程序(“proxy_pass”)将被执行。

由于不完全掌握这种行为,if 有时被认为是“邪恶的”,但在这种情况下,“邪恶的”行为对 “if” 和 “limit_except” 都是一样的,这可能是你想要的。

所以你有三个选择!

但是请注意,如果你需要设置其他指令,你必须小心不要被 if 或 limit_except 选项中的“邪恶”行为所影响。

也就是说,如果你在“if”或“limit_except”块中设置指令,可能在外面不起作用,反之亦然。因此,你必须看到如何继承默认值,或不继承,默认值代表的情况,两种方法都要考虑。

“If is Evil”页面中列出的所有潜在问题同样适用于此处的“if”和“limit_except”。建议使用基于 Lua 的脚本方法可以避免许多潜在问题。

祝你好运!

2011-12-21 17:01:04
stackoverflow用户245795
stackoverflow用户245795

我刚做了一个快速测试,这个方法对我有效:

server {
  location / {
    # 这个代理通过用于不匹配 limit_except 的请求
    proxy_pass http://127.0.0.1:8080;

    limit_except PUT POST DELETE {
      # 对于不是 PUT、POST 和 DELETE 的请求,通过 :9080
      proxy_pass http://127.0.0.1:9080;
    }
  }
}
2011-12-21 19:05:54
stackoverflow用户1818256
stackoverflow用户1818256

如果有人想要按请求方法简单地设置条件,语法是:

if ($request_method = DELETE ) {
   . . .
}
2014-06-30 12:32:52
stackoverflow用户7915295
stackoverflow用户7915295

我建议使用nginx map功能。它位于您的location块之外:

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

然后在您的location块中:

proxy_pass http://127.0.0.1:$destination

这也是正则表达式,所以您可以做一些事情,例如:

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

此外,这避免了if的使用。 它非常棒。 我使用它将WordPress集群中的所有写入流量定向到远程节点上的一个FastCGI TCP套接字,但将读取流量发送到本地FastCGI UNIX套接字。

2017-04-24 17:54:18