Как динамически добавить апстрим в Nginx?

Я имею в виду добавить upstream, но не сервер в upstream.

Это означает, что у меня нет восходящего блока, например:

upstream backend {
    # ...
}

Я хочу динамически создать восходящий блок. Это что-то вроде:

content_by_lua_block {
    upstream_block.add('backend');
    upstream_block.add_server('backend', '127.0.0.1', 8080);
    upstream_block.add_server('backend', '127.0.0.1', 8081);
    upstream_block.add_server('backend', '127.0.0.1', 8082);
    upstream_block.del_server('backend', '127.0.0.1', 8080);
}

proxy_pass http://backend

person XadillaX    schedule 22.02.2017    source источник
comment
Я не могу себе представить никакой причины для этого. Просто установите переменную и прокси-пасс к ней   -  person Alexey Ten    schedule 22.02.2017
comment
@AlexeyTen Представьте себе: у меня много групп машин, и в каждой группе есть свои машины. Все они динамичны.   -  person XadillaX    schedule 22.02.2017


Ответы (4)


Вы можете использовать balancer_by_lua* и https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md

У вас будет полный контроль над тем, какой восходящий поток выбран для данного запроса.

Вы можете самостоятельно подготовить свой код или использовать существующую исходную конфигурацию в качестве источника, используя https://github.com/openresty/lua-upstream-nginx-module

person Alexander Altshuler    schedule 23.02.2017

Я обнаружил, что модуль nginx с именем https://github.com/yzprofile/ngx_http_dyups_module соответствует моему вопросу.

person XadillaX    schedule 23.02.2017

Мой пример того, как динамически добавлять восходящие серверы на основе количества процессоров.

Серверы. Я использовал openresty и настроил его для прослушивания нескольких портов.

worker_processes auto;
error_log logs/openresty.err ;
events {
  worker_connections 1000;
}
http {
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  logs/openresty.log main;


  server {
    listen 127.0.0.1:8080;
    listen 127.0.0.1:8081;
    listen 127.0.0.1:8082;
    listen 127.0.0.1:8083;
    listen 127.0.0.1:8084;
    listen 127.0.0.1:8085;
    listen 127.0.0.1:8086;
    listen 127.0.0.1:8087;
    listen 127.0.0.1:8088;
    listen 127.0.0.1:8089;
    listen 127.0.0.1:8090;
    server_name *.*;
    location / {
      content_by_lua_block {
        --[[ local NumCores = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
        local NumCores=10
        ]]
        --
        -- local f = io.popen("ps -ef | grep nginx | wc -l ")
        local f = io.popen("/usr/sbin/sysctl  -n hw.ncpu ")
        ngx.print('CPU count: '..f:read())
        f:close()
      }
    }
  }
}

И обратный прокси-сервер динамически добавляет восходящие серверы на основе количества процессоров.

error_log logs/reverse_openresty.err ;
events {
  worker_connections 1000;
}
http {
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  logs/reverse_openresty.log main;
  upstream backend {
    server 0.0.0.1;   # just an invalid address as a place holder
    balancer_by_lua_block {
      local balancer = require "ngx.balancer"
      local start_port=8080
      local f = io.popen("/usr/sbin/sysctl  -n hw.ncpu ") -- get cpu count
      local cpu_count=tonumber(f:read())
      f:close()
      local max_port=start_port+cpu_count-2
      repeat
        local ok, err = balancer.set_current_peer('127.0.0.1', start_port)
        if not ok then
            ngx.log(ngx.ERR, "failed to set the current peer: ", err)
            return ngx.exit(500)
        end
        start_port=start_port+1
      until start_port>max_port
    }
    keepalive 10;  # connection pool
  }
  server {
    listen 80;
    location / {
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_pass http://backend; # force using http. as node server.js only have http
      }
  }
}

Конфигурация протестирована на MacOs.

person Gabriel Wu    schedule 09.06.2019
comment
+1, я знаю, что это не отвечает на вопрос, но это первый полноценный пример использования balancer_by_lua_block. - person brianNotBob; 17.04.2020

Я использую ngx_dynamic_upstream. это действительно хорошо в производстве. я разветвил оригинал от владельца и проверил исходные коды на всякий случай.

person Mustafa Özgür    schedule 25.12.2019