以下片段将一次选择一个服务器。有没有办法立刻击中它们?
upstream backend {
server 17.0.0.1:8000;
server 17.0.0.1:8001;
server 17.0.0.1:8002;
server 17.0.0.1:8003;
}
server {
location / {
proxy_pass http://backend;
}
}
答案 0 :(得分:1)
我今天遇到了类似的情况,想要对我的许多服务器广播一个GET,这些服务器正在监听API以触发git pulls。我在Nginx中找不到任何处理这种行为的东西,我不想跳到编写扩展名。
相反,我使用Python的Flask和Requests模块将一些东西混在一起:
from flask import Flask, jsonify, request
import requests
app = Flask(__name__)
# add whatever you need here to the methods
@app.route("/http/replay/<method>", methods=["POST", "GET", "PUT", "OPTIONS"])
def http_replay(method):
"""Replay an incoming request of type <method> against the parameter list of endpoints"""
endpoint_list = request.args.get("host", "")
endpoint_list = endpoint_list.split(";")
timeout = request.args.get("timeout", None) or 5
if not endpoint_list:
return jsonify(status=500,
message="Expected parameters in the form of ?host=http://host/path;host=http://host2/path")
else:
responses = []
for ep in endpoint_list:
try:
_r = requests.__getattribute__(method.lower())(ep, timeout=timeout)
status_code = _r.status_code
except requests.exceptions.Timeout:
status_code = 408 # request timeout
except requests.exceptions.RequestException:
status_code = 520
responses.append(status_code)
_r_status = set(responses)
if len(_r_status) == 1 and _r_status.pop == 200:
status = 200
else:
status = 520
return jsonify(status=status)
这只是监听路径并允许我发送请求,例如:
curl "http://localhost:5000/plugins/http/replay/POST?host=http://localhost:80/api;host=http://dev.localhost:8080/api?timeout=10"
并且如果URL参数中的所有端点都相同,则返回HTTP 200状态代码。
答案 1 :(得分:1)
如果您是通过Lua模块构建了nginx(或者您正在使用OpenResty),则以下代码段将允许您将响应广播到上游组中的所有服务器。
请求是并行进行的,完成后,将返回单独的HTTP响应和响应头。
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$is_args$args;
}
}
答案 2 :(得分:0)
以下是使用ngx_http_mirror_module的解决方案(自nginx 1.13.4起可用):
server {
location / {
proxy_pass http://17.0.0.1:8000;
mirror /s1;
mirror /s2;
mirror /s3;
}
location /s1 { internal; proxy_pass http://17.0.0.1:8001$request_uri; }
location /s2 { internal; proxy_pass http://17.0.0.1:8002$request_uri; }
location /s3 { internal; proxy_pass http://17.0.0.1:8003$request_uri; }
}
nginx将: