【问题标题】:How do I make web service calls within nginx?如何在 nginx 中进行 Web 服务调用?
【发布时间】:2018-06-26 20:28:18
【问题描述】:

什么:

我想在通过 nginx 的每个请求上从 nginx 内部向 web 服务发出请求,并根据我从 web 服务得到的响应应用一些进程。

应用:

我使用 nginx 作为反向代理,并且有多个 Web 服务将流量路由到这些服务。我想添加一个额外的 web 服务(让我们称之为 AdminService)作为管理员,该服务将处理诸如安全、计费和其他流量分析和预处理之类的事情。 对于通过 nginx 的每个请求,我需要向 AdminService 发出请求,然后管理服务将分析请求,更新一些统计信息等,并使用一些标签进行响应。然后,nginx 会根据返回的标签更新一些标头,并将请求转发到适当的 url。

我查看了 Lua 模块,它似乎没有进行 web 服务调用。 我还看到有可用的 Java、Groovy 和 Clojure 模块,这可能是我应该关注的吗?否则我应该看什么?

【问题讨论】:

    标签: nginx


    【解决方案1】:

    一种选择是使用auth_request 模块。它不是根据您的场景设计的,也不是默认的 Nginx 模块,因此您需要从源代码构建以使用 ./configure --with-http_auth_request_module 编译它。

    auth_request 用于通过远程 HTTP 调用预先验证 Nginx 请求。只要响应头是 HTTP 200,那么初始请求就会正常处理。这可用于将请求发送到您的 AdminService,响应将能够确定接下来发生的事情。

    类似:

    # Default location
    location / {
        auth_request /AdminService;
    
        # Look for X_UpstreamHost: header in the response
        auth_request_set $x_upstreamhost $upstream_http_x_upstreamhost;
    
        # Use the value of the response header to choose the internal processing host
        proxy_pass http://$x_upstreamhost;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
    
    }
    
    # Send requests for AdminService to the AdminService
    # This expects AdminService to be listening on a path called AdminService
    # and based at ##adminip##
    location /AdminService {
         proxy_pass http://##adminip##;
    }
    

    这将首先将传入请求发送到由 AdminService 定义的主机。此服务必须使用正常的 200 标头以及 x_upstreamhost:#internalHost# 进行响应。其中 #internalHost# 是您要处理请求的主机的 ip 或 dn。

    尝试一下,如果遇到问题,请发布您的服务器 {} 块,有人会看看。

    【讨论】:

    • 这看起来很有希望,我会试试看。我假设这是文档:nginx.org/en/docs/http/ngx_http_auth_request_module.html 如果在将请求发送到 x_upstreamhost 之前我能够在来自 AdminService 的响应中使用其他标头,那么这正是我所需要的。
    • 是的,这就是文档,是的,通过标头和 auth_request_set 将值传回 nginx 很容易。
    • 看起来我无法从 AdminService 的响应中访问标头。我尝试了 $http_{name} 和 $upstream_http_{name},两者似乎都给了我原始请求的标头。
    • auth_request_set $myheader $upstream_http_$myheader; 应该适用于名为 Myheader 的标头:如果标头未在原始请求中设置,则很难从那里看到如何使用它。
    【解决方案2】:

    您可以使用 nginx_lua(我喜欢 openresty 版本)通过在 access-by-lua 阶段使用脚本来处理您的自定义处理来完成此操作。

    在该脚本中,如果该 Web 服务被定义为 nginx 位置,您可以使用 ngx-location-capture 调用您的“AdminService”;或者您可以使用 http 客户端库(我使用过 this one)来调用外部服务。

    查看类似的用例here.

    【讨论】:

    • 我还没有查看过您提供的大量链接,现在想避免深入了解。我需要能够从我从“AdminService”获得的响应中访问标头,并使用其中一些标头值更新将转发到相关应用程序的请求。我能用 Lua 实现这个吗?那我将如何影响 ngx.location.capture 指令中的请求标头?
    • 当然可以。我链接的 location.capture 和 http 客户端库都返回一个字典,其中包含您可以用于您的目的的响应标头。例如if res.header["X-Foo"] == "Foo value" then do_something() end
    猜你喜欢
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    相关资源
    最近更新 更多