是否可以对所有负载均衡上游服务器执行特定请求?

时间:2019-04-02 04:57:38

标签: nginx

我正在使用NGINX服务器将HTTP请求和负载平衡请求代理到多个上游服务器。但是我有一个特定的要求,即向所有上游服务器执行特定的请求。

可以使用NGINX负载平衡吗?

我正在使用以下nginx配置

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

我有一个特定的请求(/ update),如下所示,它需要在所有上游服务器中执行,除(/ update)以外的所有其他请求都应按照负载平衡策略执行。

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location /update {
            proxy_pass http://myapp1;
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我认为在nginx中没有广播请求的证据。

我有两种选择可以实现这一目标

  1. 创建单独的服务,该服务将在所有服务器上执行给定的操作。 例如,在您的任何Applicatin服务器上创建一个php文件update.php或将其托管在nginx服务器本身上,并发出curl请求 或向所有上游服务器发送请求。

update.php

<?php
file_get_contents("srv1.example.com/update");
file_get_contents("srv2.example.com/update");
file_get_contents("srv3.example.com/update");
?>

如果您想发布可以使用curl的数据,则上面的脚本只是向服务器发出请求。

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }


        location /update {
            proxy_pass "http://servername/update.php";
        }

    }
}

  1. 使用nginx lua模块提供 ngx.location.capture_multi和ngx.location.capture函数将请求发送到所有必需的url。

https://github.com/openresty/lua-nginx-module#ngxlocationcapture_multi

答案 1 :(得分:0)

以下是可以实现此目标的有效Lua块的示例

upstream @api {
    server  10.0.0.1:80;
    server  10.0.0.2:80 backup;
}

server {
    server_name _;
    listen 443 ssl;

    location ~ ^/broadcast(?<proxy_path>/.*)$ {
        lua_need_request_body on;

        content_by_lua '
            local upstream = require "ngx.upstream"
            local servers = upstream.get_servers("@api")

            local requests = {}
            for _, srv in ipairs(servers) do
                local addr = srv.addr
                table.insert(requests, { "/proxy", { method = ngx["HTTP_" .. ngx.var.request_method], always_forward_body = true, copy_all_vars = true, vars = { proxy_host = addr } } })
            end

            local responses = { ngx.location.capture_multi(requests) }
            for i, res in ipairs(responses) do
                local addr = servers[i].addr
                ngx.say(addr, " HTTP/1.1 ", res.status)
                for header, value in pairs(res.header) do
                    ngx.say(header, ": ", value)
                end
                ngx.say()
                ngx.print(res.body)
                ngx.say()
            end
        ';
    }

    location /proxy {
        internal;
        proxy_pass http://$proxy_host$proxy_path;
    }

}