Upstream#

Fornece contexto para descrever grupos de servidores que podem ser usados na diretiva proxy_pass.

Exemplo de Configuração#

upstream backend {
    hash $remote_addr consistent;
    zone backend 1m;

    server backend1.example.com:1935  weight=5;
    server unix:/tmp/backend3;
    server backend3.example.com       service=_example._tcp resolve;

    server backup1.example.com:1935   backup;
    server backup2.example.com:1935   backup;
}

resolver 127.0.0.53 status_zone=resolver;

server {
    listen 1936;
    proxy_pass backend;
}

Diretivas#

upstream#

Sintaxe

upstream nome { ... }

Padrão

Contexto

stream

Descreve um grupo de servidores. Os servidores podem escutar em portas diferentes. Além disso, servidores escutando em TCP e sockets de domínio UNIX podem ser misturados.

Exemplo:

upstream backend {
    server backend1.example.com:1935 weight=5;
    server 127.0.0.1:1935            max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend2;
    server backend3.example.com:1935 resolve;

    server backup1.example.com:1935  backup;
}

Por padrão, as conexões são distribuídas entre os servidores usando um método de balanceamento round-robin ponderado. No exemplo acima, cada 7 conexões serão distribuídas da seguinte forma: 5 conexões vão para backend1.example.com:1935 e uma conexão para cada um dos segundo e terceiro servidores.

Se ocorrer um erro durante a comunicação com um servidor, a conexão será passada para o próximo servidor, e assim por diante até que todos os servidores funcionais sejam tentados. Se a comunicação com todos os servidores falhar, a conexão será fechada.

server#

Sintaxe

server endereço [parâmetros];

Padrão

Contexto

upstream

Define o endereço e outros parâmetros de um servidor. O endereço pode ser especificado como um nome de domínio ou endereço IP com uma porta obrigatória, ou como um caminho de socket de domínio UNIX especificado após o prefixo unix:. Um nome de domínio que resolve para vários endereços IP define múltiplos servidores de uma vez.

Os seguintes parâmetros podem ser definidos:

weight=número

Define o peso do servidor; por padrão, 1.

max_conns=número

Limita o número máximo de conexões ativas simultâneas para o servidor com proxy. O valor padrão é 0, significando que não há limite. Se o grupo de servidores não residir na memória compartilhada, a limitação funciona por cada processo worker.

max_fails=número — define o número de tentativas malsucedidas de comunicação com o servidor que devem acontecer na duração definida por fail_timeout para considerar o servidor indisponível; ele é então tentado novamente após a mesma duração.

Aqui, uma tentativa malsucedida é um erro ou timeout ao estabelecer uma conexão com o servidor.

Nota

Se uma diretiva server em um grupo resolve para múltiplos servidores, sua configuração max_fails se aplica a cada servidor individualmente.

Se um upstream contém apenas um servidor após todas as suas diretivas server serem resolvidas, a configuração max_fails não tem efeito e será ignorada.

max_fails=1

O número padrão de tentativas.

max_fails=0

Desabilita a contabilização de tentativas.

fail_timeout=tempo — define o período de tempo durante o qual um número especificado de tentativas malsucedidas de comunicação com o servidor (max_fails) deve acontecer para considerar o servidor indisponível. O servidor então permanece indisponível pela mesma quantidade de tempo antes de ser tentado novamente.

Por padrão, isso é definido como 10 segundos.

Nota

Se uma diretiva server em um grupo resolve para múltiplos servidores, sua configuração fail_timeout se aplica a cada servidor individualmente.

Se um upstream contém apenas um servidor após todas as suas diretivas server serem resolvidas, a configuração fail_timeout não tem efeito e será ignorada.

backup

Marca o servidor como um servidor de backup. Ele receberá requisições quando os servidores primários estiverem indisponíveis.

down

Marca o servidor como permanentemente indisponível.

drain (PRO)

Marca o servidor como drenando; isso significa que ele recebe apenas requisições das sessões que foram vinculadas anteriormente com sticky. Caso contrário, ele se comporta de forma similar a down.

Aviso

O parâmetro backup não pode ser usado junto com os métodos de balanceamento de carga hash e random.

Os parâmetros down e drain são mutuamente exclusivos.

resolve

Habilita o monitoramento de mudanças na lista de endereços IP que corresponde a um nome de domínio, atualizando-a sem recarregar a configuração. O grupo deve residir em uma zona de memória compartilhada; além disso, um resolver deve ser definido.

service=nome

Habilita a resolução de registros DNS SRV e define o nome do serviço. Para que este parâmetro funcione, o parâmetro resolve também deve ser especificado, sem especificar a porta do servidor no nome do host.

Se não houver pontos no nome do serviço, o nome é formado de acordo com o padrão RFC: o nome do serviço é prefixado com _, então _tcp é adicionado após um ponto. Assim, o nome do serviço http resultará em _http._tcp.

O Angie resolve os registros SRV combinando o nome do serviço normalizado e o nome do host e obtendo a lista de servidores para a combinação via DNS, junto com suas prioridades e pesos.

  • Registros SRV de prioridade máxima (aqueles que compartilham o valor mínimo de prioridade) resolvem para servidores primários, e outros registros tornam-se servidores de backup. Se backup for definido com server, registros SRV de prioridade máxima resolvem para servidores de backup, e outros registros são ignorados.

  • O peso é similar ao parâmetro weight da diretiva server. Se o peso for definido tanto pela diretiva quanto pelo registro SRV, o peso definido pela diretiva é usado.

Este exemplo irá procurar o registro _http._tcp.backend.example.com:

server backend.example.com service=http resolve;

sid=id

Define o ID do servidor no grupo. Se o parâmetro não for especificado, o ID é definido como um hash MD5 hexadecimal do endereço IP e porta ou caminho do socket de domínio UNIX.

slow_start=time

Define o tempo para um servidor recuperar seu peso ao retornar ao serviço com os métodos de balanceamento de carga round-robin ou least_conn.

Se o parâmetro estiver definido e um servidor for novamente considerado saudável após uma falha de acordo com max_fails e upstream_probe (PRO), o servidor gradualmente recupera seu peso designado durante o período de tempo especificado.

Se o parâmetro não estiver definido, em uma situação similar o servidor imediatamente começa a trabalhar com seu peso designado.

Nota

Se apenas um server for especificado no upstream, slow_start não tem efeito e será ignorado.

state (PRO)#

Sintaxe

state file;

Padrão

Contexto

upstream

Especifica o file onde a lista de servidores upstream é armazenada persistentemente. Ao instalar a partir dos nossos pacotes, um diretório dedicado /var/lib/angie/state/ (/var/db/angie/state/ no FreeBSD) é criado com as permissões apropriadas para armazenar tais arquivos, então você só precisa adicionar o nome do arquivo na configuração:

upstream backend {

    zone backend 1m;
    state /var/lib/angie/state/<NOME DO ARQUIVO>;
}

O formato da lista de servidores aqui é similar ao s_server. O conteúdo do arquivo muda sempre que servidores são modificados na seção /config/stream/upstreams/ via API de configuração. O arquivo é lido na inicialização do Angie ou no recarregamento da configuração.

Aviso

Para usar a diretiva state em um bloco upstream, não deve haver diretivas server nele, mas uma zona de memória compartilhada (zone) é necessária.

zone#

Sintaxe

zone name [size];

Padrão

Contexto

upstream

Define o nome e tamanho da zona de memória compartilhada que armazena a configuração e estado de execução do grupo, compartilhada entre processos worker. Múltiplos grupos podem usar a mesma zona. Neste caso, é suficiente especificar o tamanho apenas uma vez.

backup_switch (PRO)#

Sintaxe

backup_switch permanent[=time];

Padrão

Contexto

upstream

A diretiva habilita a capacidade de iniciar a seleção de servidor não do grupo primário, mas do grupo ativo, ou seja, aquele onde um servidor foi encontrado com sucesso anteriormente. Se um servidor não puder ser encontrado no grupo ativo para a próxima requisição, e a busca se mover para o grupo de backup, este grupo de backup se torna ativo, e requisições subsequentes são primeiro direcionadas para servidores neste grupo.

Se o parâmetro permanent for definido sem um valor de tempo, o grupo permanece ativo após a seleção, e a re-verificação automática de grupos com níveis de prioridade mais baixos não ocorre. Se time for especificado, o status ativo do grupo expira após o intervalo especificado, e o balanceador de carga novamente verifica grupos com níveis de prioridade mais baixos, retornando a eles se os servidores estiverem funcionando normalmente.

Exemplo:

upstream media_backend {
    server primary1.example.com:1935;
    server primary2.example.com:1935;

    server reserve1.example.com:1935 backup;
    server reserve2.example.com:1935 backup;

    backup_switch permanent=2m;
}

Se o balanceador de carga alternar dos servidores primários para o grupo de backup, todas as requisições subsequentes são tratadas por este grupo de backup por 2 minutos. Após 2 minutos expirarem, o balanceador de carga re-verifica os servidores primários e os torna ativos novamente se estiverem funcionando normalmente.

feedback (PRO)#

Sintaxe

feedback variable [inverse] [factor=number] [account=condition_variable];

Padrão

Contexto

upstream

Habilita um mecanismo de balanceamento de carga baseado em feedback para o upstream. Ele ajusta dinamicamente as decisões de balanceamento de carga multiplicando o peso de cada servidor proxy pela média do valor de feedback, que muda ao longo do tempo baseado no valor da variable e está sujeito a uma condição opcional.

Os seguintes parâmetros podem ser especificados:

variable

A variável da qual o valor de feedback é obtido. Ela deve representar uma métrica de desempenho ou saúde; assume-se que seja fornecida pelo servidor.

O valor é avaliado com cada resposta do servidor e considerado na média móvel de acordo com as configurações inverse e factor.

inverse

Se o parâmetro estiver definido, o valor de feedback é interpretado inversamente: valores menores indicam melhor desempenho.

factor

O fator pelo qual o valor de feedback é ponderado ao calcular a média. Valores válidos são inteiros de 0 a 99. O padrão é 90.

A média é calculada usando a fórmula de suavização exponencial.

Quanto maior o fator, menos os novos valores afetam a média; se 90 for especificado, 90% do valor anterior será considerado e apenas 10% do novo valor.

account

Especifica uma variável de condição que controla como as conexões são contabilizadas no cálculo. O valor médio é atualizado com o valor de feedback apenas se a variável de condição não for igual a "" ou "0".

Nota

Por padrão, o tráfego de sondas não é incluído no cálculo; combinar a variável $upstream_probe com account permite incluí-las ou até mesmo excluir todo o resto.

Exemplo:

upstream backend {

    zone backend 1m;

    feedback $feedback_value factor=80 account=$condition_value;

    server backend1.example.com:1935  weight=1;
    server backend2.example.com:1935  weight=2;
}

map $protocol $feedback_value {
    "TCP"                      100;
    "UDP"                      75;
    default                    10;
}

map $upstream_probe $condition_value {
    "high_priority" "1";
    "low_priority"  "0";
    default         "1";
}

Esta configuração categoriza servidores por níveis de feedback baseados nos protocolos usados em sessões individuais, e também adiciona uma condição em $upstream_probe para contabilizar apenas sondas high_priority ou sessões regulares de cliente.

hash#

Sintaxe

hash key [consistent];

Padrão

Contexto

upstream

Especifica um método de balanceamento de carga para o grupo onde o mapeamento cliente-servidor é determinado usando um valor de chave hash. A chave pode conter texto, variáveis e suas combinações. Note que qualquer adição ou remoção de servidores do grupo pode resultar no remapeamento da maioria das chaves para servidores diferentes. O método é compatível com a biblioteca Perl Cache::Memcached.

Exemplo de uso:

hash $remote_addr;

Ao usar nomes de domínio que resolvem para múltiplos endereços IP (por exemplo, com o parâmetro resolve), o servidor não ordena os endereços recebidos, então sua ordem pode diferir entre diferentes servidores, o que afeta a distribuição de clientes. Para garantir distribuição consistente, use o parâmetro consistent.

Se o parâmetro consistent for especificado, o método de hash consistente ketama será usado em vez do método acima. O método garante que quando um servidor é adicionado ou removido do grupo, apenas um número mínimo de chaves será remapeado para outros servidores. Usar o método para servidores de cache fornece uma taxa de acerto de cache mais alta. O método é compatível com a biblioteca Perl Cache::Memcached::Fast com o parâmetro ketama_points definido como 160.

least_conn#

Sintaxe

least_conn;

Padrão

Contexto

upstream

Especifica um método de balanceamento de carga para o grupo onde uma conexão é passada para o servidor com o menor número de conexões ativas, levando em conta os pesos dos servidores. Se vários servidores forem adequados, eles são selecionados ciclicamente (round-robin) com seus pesos levados em conta.

least_time (PRO)#

Sintaxe

least_time connect | first_byte | last_byte [factor=number] [account=condition_variable];

Padrão

Contexto

upstream

Especifica um método de balanceamento de carga para o grupo onde a probabilidade de passar uma conexão para um servidor ativo é inversamente proporcional ao seu tempo médio de resposta; quanto menor ele for, mais conexões o servidor receberá.

connect

A diretiva leva em conta o tempo médio para estabelecer uma conexão.

first_byte

A diretiva usa o tempo médio para receber o primeiro byte da resposta.

last_byte

A diretiva usa o tempo médio para receber a resposta completa.

factor

Executa a mesma função que response_time_factor (PRO), e o sobrescreve se o parâmetro for especificado.

account

Especifica uma variável de condição que controla quais conexões são contabilizadas no cálculo. O valor médio é atualizado apenas se a variável de condição da conexão não for igual a "" ou "0".

Nota

Por padrão, sondas não são incluídas no cálculo; combinar a variável $upstream_probe com account permite incluí-las ou até mesmo excluir todo o resto.

Os valores atuais são apresentados como connect_time, first_byte_time, e last_byte_time no objeto health do servidor entre as métricas de upstream na API.

random#

Sintaxe

random [two];

Padrão

Contexto

upstream

Especifica um método de balanceamento de carga para o grupo onde uma conexão é passada para um servidor selecionado aleatoriamente, levando em conta os pesos dos servidores.

Se o parâmetro opcional two for especificado, o Angie seleciona aleatoriamente dois servidores e então escolhe um servidor usando o método especificado. O método padrão é least_conn, que passa a conexão para o servidor com o menor número de conexões ativas.

response_time_factor (PRO)#

Sintaxe

response_time_factor number;

Padrão

response_time_factor 90;

Contexto

upstream

Especifica para o método de balanceamento de carga least_time (PRO) o fator de suavização para o valor anterior ao calcular o tempo médio de resposta usando a fórmula de média móvel exponencialmente ponderada.

Quanto maior o number especificado, menos os novos valores afetam a média; se 90 for especificado, 90% do valor anterior será considerado e apenas 10% do novo valor. Valores válidos são de 0 a 99 inclusive.

Os resultados atuais do cálculo são apresentados como connect_time (tempo para estabelecer uma conexão), first_byte_time (tempo para receber o primeiro byte da resposta), e last_byte_time (tempo para receber a resposta completa) no objeto health do servidor entre as métricas de upstream na API.

Nota

Apenas respostas bem-sucedidas são consideradas no cálculo; o que constitui uma resposta mal-sucedida é determinado pelas diretivas proxy_next_upstream.

sticky#

Sintaxe

sticky route $variable...;

sticky learn zone=zone create=$create_var1... lookup=$lookup_var1... [connect] [norefresh] [timeout=time];

sticky learn lookup=$lookup_var1... remote_action=uri remote_result=$remote_var [remote_uri=uri];

Padrão

Contexto

upstream

Configura sessões persistentes entre clientes e servidores upstream, dependendo do modo especificado no primeiro parâmetro. Para gradualmente tirar servidores com sticky de rotação, você pode usar a opção drain (PRO) no bloco server.

Aviso

A diretiva sticky deve aparecer após todas as diretivas de método de balanceamento de carga, caso contrário não funcionará.

Este modo usa identificadores de rota predefinidos que podem ser incorporados em propriedades de conexão acessíveis ao Angie. É menos flexível, pois depende de valores predefinidos, mas é mais adequado se tais identificadores já estiverem em uso.

Aqui, ao estabelecer uma conexão, o servidor upstream pode atribuir uma rota ao cliente e retornar seu identificador de uma forma conhecida por ambas as partes. O identificador de rota deve usar o valor do parâmetro sid da diretiva server. Note que o parâmetro é adicionalmente hasheado se a diretiva sticky_secret for especificada.

Conexões subsequentes de clientes que desejam usar esta rota devem conter o identificador emitido pelo servidor, de tal forma que ele termine em variáveis do Angie.

Os parâmetros da diretiva especificam variáveis para roteamento. Para selecionar o servidor para onde a conexão de entrada é direcionada, a primeira variável não vazia é usada; ela é então comparada com o parâmetro sid da diretiva server. Se a seleção do servidor falhar ou o servidor selecionado não puder aceitar a conexão, outro servidor será selecionado de acordo com o método de balanceamento de carga configurado.

Aqui o Angie procura o identificador de rota na variável $route, que recebe seu valor baseado em $ssl_preread_server_name (note que ssl_preread deve estar habilitado):

stream {

    map $ssl_preread_server_name $route {

        a.example.com            a;
        b.example.com            b;
        default                  "";
    }

    upstream backend {

        server 127.0.0.1:8081 sid=a;
        server 127.0.0.1:8082 sid=b;

        sticky route $route;
    }

    server {

        listen 127.0.0.1:8080;

        ssl_preread on;

        proxy_pass backend;
    }
}

A diretiva sticky leva em conta o estado dos servidores em upstream:

  • Servidores marcados como down ou temporariamente indisponíveis devido a falhas são excluídos da seleção.

  • Servidores que atingiram o número máximo de conexões (ao usar max_conns) são temporariamente ignorados.

  • Servidores com a opção drain (PRO) podem ser selecionados para criar novas sessões no modo sticky quando os identificadores correspondem.

  • Se um servidor anteriormente indisponível se recuperar, sticky automaticamente retoma seu uso.

O comportamento de sticky pode ser configurado adicionalmente com as diretivas sticky_secret e sticky_strict. Se sticky falhar ao selecionar um servidor ou ele estiver indisponível, a requisição será tratada de acordo com o método de balanceamento de carga selecionado, a menos que a diretiva sticky_strict esteja habilitada. No modo sticky_strict on;, a requisição é rejeitada com um erro.

Zonas de memória compartilhada especificadas no parâmetro zone da diretiva sticky não podem ser compartilhadas entre diferentes grupos upstream; cada grupo deve usar sua própria zona.

sticky_secret#

Sintaxe

sticky_secret string;

Padrão

Contexto

upstream

Adiciona string como salt à função hash MD5 para a diretiva sticky no modo route. String pode conter variáveis, por exemplo $remote_addr:

upstream backend {
    server 127.0.0.1:8081 sid=a;
    server 127.0.0.1:8082 sid=b;

    sticky route $route;
    sticky_secret my_secret.$remote_addr;
}

O salt é adicionado após o valor hasheado; para verificar independentemente o mecanismo de hashing:

$ echo -n "<VALUE><SALT>" | md5sum

sticky_strict#

Sintaxe

sticky_strict on | off;

Padrão

sticky_strict off;

Contexto

upstream

Quando habilitado, o Angie retornará um erro de conexão para o cliente se o servidor desejado estiver indisponível, em vez de fazer fallback para outro servidor disponível, que é o comportamento padrão quando nenhum servidor correspondente é encontrado.

Variáveis Integradas#

O módulo stream_upstream suporta as seguintes variáveis integradas:

$sticky_sessid#

Usado com remote_action em sticky; armazena o identificador de sessão inicial obtido de lookup.

$sticky_sid#

Usado com remote_action em sticky; armazena o identificador do servidor previamente associado com a sessão.

sticky_sid contém o valor do parâmetro sid= da diretiva server no bloco upstream, se especificado, ou o hash MD5 do nome do servidor.

$upstream_addr#

armazena o endereço IP e porta, ou o caminho para o socket de domínio UNIX do servidor upstream. Se vários servidores foram contatados durante o proxy, seus endereços são separados por vírgulas, por exemplo:

192.168.1.1:1935, 192.168.1.2:1935, unix:/tmp/sock

Se um servidor não puder ser selecionado, a variável mantém o nome do grupo de servidores.

$upstream_bytes_received#

número de bytes recebidos de um servidor upstream. Valores de várias conexões são separados por vírgulas e dois pontos como endereços na variável $upstream_addr.

$upstream_bytes_sent#

número de bytes enviados para um servidor upstream. Valores de várias conexões são separados por vírgulas e dois pontos como endereços na variável $upstream_addr.

$upstream_connect_time#

tempo para conectar ao servidor upstream; o tempo é mantido em segundos com resolução de milissegundos. Tempos de várias conexões são separados por vírgulas e dois pontos como endereços na variável $upstream_addr.

$upstream_first_byte_time#

tempo para receber o primeiro byte de dados; o tempo é mantido em segundos com resolução de milissegundos. Tempos de várias conexões são separados por vírgulas como endereços na variável $upstream_addr.

$upstream_session_time#

duração da sessão em segundos com resolução de milissegundos. Tempos de várias conexões são separados por vírgulas como endereços na variável $upstream_addr.

$upstream_sticky_status#

Status das conexões sticky.

""

Conexão roteada para um grupo de servidores onde sticky não está habilitado.

NEW

Conexão não contém informações sticky.

HIT

Conexão com informações sticky roteada para o servidor desejado.

MISS

Conexão com informações sticky roteada para um servidor selecionado pelo algoritmo de balanceamento de carga.

Valores de múltiplas conexões são separados por vírgulas e dois pontos, similar aos endereços na variável $upstream_addr.