В Nginx Upstream представляет конфигурацию балансировки нагрузки при обратном прокси. В данном контексте мы расширяем понятие Upstream следующими характеристиками:
Оба Upstream и DNS-разрешение позволяют связывать группы IP-адресов с одним хостом, но имеют различия:
Это локальный модуль обратного прокси, который применяется как для сервера, так и для клиента.
Поддерживает динамическую конфигурацию, которая может быть использована для системы открытия услуг. В настоящее время workflow-k8s может быть интегрирован с API сервером Kubernetes.
Имя Upstream не должно содержать номер порта, но запросы Upstream поддерживают указание портов (если используется протокол, отличный от встроенного, имя Upstream временно должно содержать номер порта).
Каждый Upstream имеет уникальное имя UpstreamName и добавляет набор адресов, которые могут быть:
class UpstreamManager
{
public:
static int upstream_create_consistent_hash(const std::string& name,
upstream_route_t consistent_hash);
static int upstream_create_weighted_random(const std::string& name,
bool try_another);
static int upstream_create_manual(const std::string& name,
upstream_route_t select,
bool try_another,
upstream_route_t consistent_hash);
static int upstream_create_vnswrr(const std::string& name);
static int upstream_delete(const std::string& name);
public:
static int upstream_add_server(const std::string& name,
const std::string& address);
static int upstream_add_server(const std::string& name,
const std::string& address,
const struct AddressParams *address_params);
static int upstream_remove_server(const std::string& name,
const std::string& address);
...
}
Настройте локальный обратный прокси, чтобы все запросы к my_proxy.name
были равномерно распределены между шестью целевыми серверами.
UpstreamManager::upstream_create_weighted_random(
"my_proxy.name",
true); // если встретили машину с мелtdown, продолжайте пытаться до тех пор пока не найдете рабочую или все машины будут в состоянии мелtdown
UpstreamManager::upstream_add_server("my_proxy.name", "192.168.2.100:8081");
UpstreamManager::upstream_add_server("my_proxy.name", "192.168.2.100:8082");
UpstreamManager::upstream_add_server("my_proxy.name", "192.168.10.10");
UpstreamManager::upstream_add_server("my_proxy.name", "test.sogou.com:8080");
UpstreamManager::upstream_add_server("my_proxy.name", "abc.sogou.com");
UpstreamManager::upstream_add_server("my_proxy.name", "abc.sogou.com");
UpstreamManager::upstream_add_server("my_proxy.name", "/dev/unix_domain_socket_sample");
auto *http_task = WFTaskFactory::create_http_task("http://my_proxy.name/somepath?a=10", 0, 0, nullptr);
http_task->start();
Основные принципы:
try_another
установлен в true
, выбирается случайный живой сервер из всех живых.Настройте локальный обратный прокси, чтобы все запросы к weighted.random
были распределены между тремя целевыми серверами с весами 5, 20 и 1 соответственно.
UpstreamManager::upstream_create_weighted_random(
"weighted.random",
false); // если встретили машину с мелtdown, прекращаем попытки, в этом случае запрос завершится неудачей
AddressParams address_params = ADDRESS_PARAMS_DEFAULT;
address_params.weight = 5; // вес равен 5
UpstreamManager::upstream_add_server("weighted.random", "192.168.2.100:8081", &address_params); // вес 5
address_params.weight = 20; // вес равен 20
UpstreamManager::upstream_add_server("weighted.random", "192.168.2.100:8082", &address_params); // вес 20
UpstreamManager::upstream_add_server("weighted.random", "abc.sogou.com"); // вес 1
auto *http_task = WFTaskFactory::create_http_task("http://weighted.random:9090", 0, 0, nullptr);
http_task->start();
Основные принципы:
try_another
установлен в true
, выбирается случайный живой сервер из всех живых по весу.UpstreamManager::upstream_create_consistent_hash(
"abc.local",
nullptr); // nullptr указывает на использование внутренней функции хэша
UpstreamManager::upstream_add_server("abc.local", "192.168.2.100:8081");
UpstreamManager::upstream_add_server("abc.local", "192.168.2.100:8082");
UpstreamManager::upstream_add_server("abc.local", "192.168.10.10");
UpstreamManager::upstream_add_server("abc.local", "test.sogou.com:8080");
UpstreamManager::upstream_add_server("abc.local", "abc.sogou.com");
auto *http_task = WFTaskFactory::create_http_task("http://abc.local/service/method", 0, 0, nullptr);
http_task->start();
Основные принципы:
std::hash
для вычисления значения узла на основе адреса узла, виртуального индекса и количества добавлений этого адреса к этому upstream.std::hash
для вычисления значения данных на основе пути, запроса и фрагмента.upstream_add_server()
указаны параметры AddressParams
с весом, каждый основной сервер будет рассматриваться как 16 * weight виртуальных узлов, что полезно для использования взвешенного хэша или когда требуется меньшая стандартная дисперсия.UpstreamManager::upstream_create_consistent_hash(
"abc.local",
[](const char *path, const char *query, const char *fragment) -> unsigned int {
unsigned int hash = 0;
while (*path)
hash = (hash * 131) + (*path++);
while (*query)
hash = (hash * 131) + (*query++);
while (*fragment)
hash = (hash * 131) + (*fragment++);
return hash;
});
UpstreamManager::upstream_add_server("abc.local", "192.168.2.100:8081");
UpstreamManager::upstream_add_server("abc.local", "192.168.2.100:8082");
UpstreamManager::upstream_add_server("abc.local", "192.168.10.10");
UpstreamManager::upstream_add_server("abc.local", "test.sogou.com:8080");
UpstreamManager::upstream_add_server("abc.local", "abc.sogou.com");
auto *http_task = WFTaskFactory::create_http_task("http://abc.local/sompath?a=1#flag100", 0, 0, nullptr);
http_task->start();
Основные принципы:
UpstreamManager::upstream_create_manual(
"xyz.cdn",
[](const char *path, const char *query, const char *fragment) -> unsigned int {
return atoi(fragment);
},
true, // если выбранная цель находится в состоянии мелtdown, будет выполнена вторая попытка выбора
nullptr); // nullptr указывает на использование внутренней функции хэша для второй попытки выбора
UpstreamManager::upstream_add_server("xyz.cdn", "192.168.2.100:8081");
UpstreamManager::upstream_add_server("xyz.cdn", "192.168.2.100:8082");
UpstreamManager::upstream_add_server("xyz.cdn", "192.168.10.10");
UpstreamManager::upstream_add_server("xyz.cdn", "test.sogou.com:8080");
UpstreamManager::upstream_add_server("xyz.cdn", "abc.sogou.com");
auto *http_task = WFTaskFactory::create_http_task("http://xyz.cdn/sompath?key=somename#3", 0, 0, nullptr);
http_task->start();
Основные принципы:
try_another
установлена в true
, будет выполнена вторая попытка выбора с помощью функции хэша.UpstreamManager::upstream_create_weighted_random(
"simple.name",
true); // Установка одного мастера и одного слейва не имеет значения
AddressParams address_params = ADDRESS_PARAMS_DEFAULT;
address_params.server_type = 0;
UpstreamManager::upstream_add_server("simple.name", "main01.test.ted.bj.sogou", &address_params); // мастер
address_params.server_type = 1;
UpstreamManager::upstream_add_server("simple.name", "backup01.test.ted.gd.sogou", &address_params); // слейв
auto *http_task = WFTaskFactory::create_http_task("http://simple.name/request", 0, 0, nullptr);
auto *redis_task = WFTaskFactory::create_redis_task("redis://simple.name/2", 0, nullptr);
redis_task->get_req()->set_query("MGET", {"key1", "key2", "key3", "key4"});
(*http_task * redis_task).start();
Основные принципы:
UpstreamManager::upstream_create_consistent_hash(
"abc.local",
nullptr); // nullptr указывает на использование встроенной функции Consistent Hashing
AddressParams address_params = ADDRESS_PARAMS_DEFAULT;
address_params.server_type = 0;
address_params.group_id = 1001;
UpstreamManager::upstream_add_server("abc.local", "192.168.2.100:8081", &address_params); // мастер группы 1001
address_params.server_type = 1;
address_params.group_id = 1001;
UpstreamManager::upstream_add_server("abc.local", "192.168.2.100:8082", &address_params); // слейв группы 1001
address_params.server_type = 0;
address_params.group_id = 1002;
UpstreamManager::upstream_add_server("abc.local", "main01.test.ted.bj.sogou", &address_params); // мастер группы 1002
address_params.server_type = 1;
address_params.group_id = 1002;
UpstreamManager::upstream_add_server("abc.local", "backup01.test.ted.gd.sogou", &address_params); // слейв группы 1002
address_params.server_type = 1;
address_params.group_id = -1;
UpstreamManager::upstream_add_server("abc.local", "test.sogou.com:8080", &address_params); // слейв без группы
UpstreamManager::upstream_add_server("abc.local", "abc.sogou.com"); // мастер без группы
auto *http_task = WFTaskFactory::create_http_task("http://abc.local/service/method", 0, 0, nullptr);
http_task->start();
Основные принципы:
UpstreamManager::upstream_create_vnswrr("nvswrr.random");
AddressParams address_params = ADDRESS_PARAMS_DEFAULT;
address_params.weight = 3; // вес 3
UpstreamManager::upstream_add_server("nvswrr.random", "192.168.2.100:8081", &address_params); // вес 3
address_params.weight = 2; // вес 2
UpstreamManager::upstream_add_server("nvswrr.random", "192.168.2.100:8082", &address_params); // вес 2
UpstreamManager::upstream_add_server("nvswrr.random", "abc.sogou.com"); // вес 1
auto *http_task = WFTaskFactory::create_http_task("http://nvswrr.random:9090", 0, 0, nullptr);
http_task->start();
Основные принципы:
При заполнении URIHost запроса значением UpstreamName, выбирается соответствующий upstream для выполнения запроса. Далее выбирается адрес из списка адресов upstream:
round-robin/weighted-round-robin: эквивалентна стратегии 1, временно недоступна. Рекомендованная стратегия для обычных пользователей — 2, которая обеспечивает хорошую отказоустойчивость и масштабируемость. Для сложных требований рекомендуется использовать стратегию 3, позволяющую настраивать логику выбора.
struct EndpointParams
{
size_t max_connections;
int connect_timeout;
int response_timeout;
int ssl_connect_timeout;
bool use_tls_sni;
};
static constexpr struct EndpointParams ENDPOINT_PARAMS_DEFAULT =
{
.max_connections = 200,
.connect_timeout = 10 * 1000,
.response_timeout = 10 * 1000,
.ssl_connect_timeout = 10 * 1000,
.use_tls_sni = false,
};
struct AddressParams
{
struct EndpointParams endpoint_params;
unsigned int dns_ttl_default;
unsigned int dns_ttl_min;
unsigned int max_fails;
unsigned short weight;
int server_type;
int group_id;
};
static constexpr struct AddressParams ADDRESS_PARAMS_DEFAULT =
{
.endpoint_params = ENDPOINT_PARAMS_DEFAULT,
.dns_ttl_default = 12 * 3600,
.dns_ttl_min = 180,
.max_fails = 200,
.weight = 1, // только для мастера в UPSTREAM_WEIGHTED_RANDOM
.server_type = 0,
.group_id = -1,
};
Каждый адрес можно настроить своими параметрами:
Среднее время восстановления (Mean Time To Repair, MTTR) — это среднее время, необходимое для восстановления системы после выхода из строя.
Эффект цепного реагирования — это ситуация, когда одна система начинает зависеть от другой системы, и если первая система выходит из строя, то вторая также начинает зависеть от третьей системы и так далее. Это приводит к тому, что весь комплекс систем становится крайне уязвимым к отказам.
Если число ошибок или аномалий достигнет порогового значения, система временно считает этот компонент недоступным и прекращает его использование. После истечения времени MTTR система снова начинает проверять доступность этого компонента.
MTTR = 30 секунд, временно не настраивается, но планируется предоставление возможности настройки пользователю. Если число последовательных ошибок достигнет максимума (по умолчанию 200), адрес будет заблокирован на 30 секунд. Адрес, находящийся в состоянии фузинга, будет удален из выборки, если он выбран стратегией.
Обратите внимание, что если выполняются условия 1-4, задача получит ошибку WFT_ERR_UPSTREAM_UNAVAILABLE = 1004:
```text
Настройка UpstreamManager::upstream_add_server("my_proxy.name", "192.168.10.10");
Запрос http://my_proxy.name:456/test.html => http://192.168.10.10:456/test.html
Запрос http://my_proxy.name/test.html => http://192.168.10.10:80/test.html
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )