Conexões, Sessões, Requisições, Logs#
Mecanismos de processamento de conexão#
O Angie suporta vários métodos de processamento de conexão. A disponibilidade de um método específico depende da plataforma sendo utilizada. Em plataformas que suportam múltiplos métodos, o Angie normalmente seleciona o método mais eficiente automaticamente. No entanto, se necessário, um método de processamento de conexão pode ser explicitamente escolhido usando a diretiva use.
Os seguintes métodos de processamento de conexão estão disponíveis:
Método | Descrição |
---|---|
| Um método padrão. O módulo de suporte é construído automaticamente em
plataformas que não possuem métodos mais eficientes. As opções de
construção |
| Um método padrão. O módulo de suporte é construído automaticamente em
plataformas que não possuem métodos mais eficientes. As opções de
construção |
| Um método eficiente disponível no FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0, e macOS. |
| Um método eficiente disponível no Linux 2.6+. |
| Um método eficiente disponível no Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+, e Tru64 UNIX 5.1A+. |
| O método |
Processamento de requisições HTTP#
Uma requisição HTTP passa por uma série de fases, onde um tipo específico de processamento é realizado em cada fase.
| A fase inicial. O módulo RealIP é invocado durante esta fase. |
| A fase onde as diretivas do módulo Rewrite,
definidas em um bloco |
| Uma fase especial onde um location é selecionado baseado na URI da requisição. |
| Similar à fase |
| Uma fase especial onde a requisição é redirecionada para um novo location,
como na fase |
| Durante esta fase, módulos padrão do Angie como Limit Req registram seus manipuladores. |
| A fase onde a autorização do cliente para fazer a requisição é verificada, normalmente invocando módulos padrão do Angie como Auth Basic. |
| Uma fase especial onde a diretiva satisfy any é processada. |
| Diretivas de módulos padrão, como try_files e mirror, registram seus manipuladores durante esta fase. |
| A fase onde a resposta é normalmente gerada. Múltiplos módulos padrão do Angie registram seus manipuladores neste estágio, incluindo Index. As diretivas proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass e grpc_pass também são tratadas aqui. Os manipuladores são chamados sequencialmente até que um deles produza a saída. |
| A fase final, onde o registro da requisição é realizado. Atualmente, apenas o módulo Log registra seu manipulador neste estágio para registro de acesso. |
Processamento de sessões TCP/UDP#
Uma sessão TCP/UDP de um cliente passa por uma série de fases, onde um tipo específico de processamento é realizado em cada fase:
| A fase inicial após aceitar uma conexão do cliente. O módulo RealIP é invocado nesta fase. |
| Uma fase preliminar para verificar o acesso. Os módulos Set são invocados durante esta fase. |
| A fase para limitar o acesso do cliente antes do processamento real dos dados. O módulo Access é invocado neste estágio. |
| A fase onde ocorre a terminação TLS/SSL. O módulo SSL é invocado durante esta fase. |
| A fase para ler os bytes iniciais de dados no buffer de preread para permitir que módulos como SSL Preread analisem os dados antes do processamento. |
| Uma fase obrigatória onde os dados são realmente processados, normalmente envolvendo o módulo Return para enviar uma resposta ao cliente. A diretiva proxy_pass também é tratada aqui. |
| A fase final onde o resultado do processamento da sessão do cliente é registrado. O módulo Log é invocado nesta fase. |
Processamento de requisições#
Seleção de servidor virtual#
Inicialmente, uma conexão é criada dentro do contexto de um servidor padrão. O nome do servidor pode então ser determinado nos seguintes estágios do processamento da requisição, cada um dos quais está envolvido na seleção da configuração do servidor:
Durante o handshake SSL, antecipadamente, de acordo com o SNI.
Após processar a linha da requisição.
Após processar o campo de cabeçalho
Host
.
Se o nome do servidor não for determinado após processar a linha da requisição ou o
campo de cabeçalho Host
, o Angie usará um nome vazio como nome do servidor.
Em cada um desses estágios, diferentes configurações de servidor podem ser aplicadas. Portanto, certas diretivas devem ser especificadas com cuidado:
No caso da diretiva ssl_protocols, a lista de protocolos é definida pela biblioteca OpenSSL antes que a configuração do servidor seja aplicada de acordo com o nome solicitado através do SNI. Como resultado, os protocolos devem ser especificados apenas para o servidor padrão.
As diretivas client_header_buffer_size e merge_slashes são aplicadas antes de ler a linha da requisição. Portanto, essas diretivas usam ou a configuração do servidor padrão ou a configuração do servidor escolhida por SNI.
No caso das diretivas ignore_invalid_headers, large_client_header_buffers, e underscores_in_headers, que estão envolvidas no processamento dos campos de cabeçalho da requisição, a configuração do servidor depende adicionalmente de ter sido atualizada de acordo com a linha da requisição ou o campo de cabeçalho
Host
.Uma resposta de erro é tratada usando a diretiva error_page no servidor que está atualmente processando a requisição.
Servidores virtuais baseados em nome#
O Angie primeiro determina qual servidor deve tratar a requisição. Considere uma configuração simples onde todos os três servidores virtuais escutam na porta 80:
server {
listen 80;
server_name example.org www.example.org;
# ...
}
server {
listen 80;
server_name example.net www.example.net;
# ...
}
server {
listen 80;
server_name example.com www.example.com;
# ...
}
Nesta configuração, o Angie determina qual servidor deve tratar a
requisição baseado exclusivamente no campo de cabeçalho Host
. Se o valor deste
cabeçalho não corresponder a nenhum nome de servidor ou se a requisição não contiver este
campo de cabeçalho, o Angie roteará a requisição para o servidor padrão desta
porta. Na configuração acima, o servidor padrão é o primeiro — que é o
comportamento padrão do Angie. Também pode ser explicitamente especificado qual
servidor deve ser o padrão usando o parâmetro default_server
na
diretiva listen:
server {
listen 80 default_server;
server_name example.net www.example.net;
# ...
}
Nota
Note que o servidor padrão é uma propriedade do socket de escuta, não do nome do servidor.
Nomes internacionalizados#
Nomes de domínio internacionalizados (IDNs) devem ser especificados usando uma representação ASCII (Punycode) na diretiva server_name:
server {
listen 80;
server_name xn--e1afmkfd.xn--80akhbyknj4f; # пример.испытание
# ...
}
Prevenindo requisições com nomes de servidor indefinidos#
Se requisições sem o campo de cabeçalho Host
não devem ser permitidas, um
servidor que simplesmente descarta tais requisições pode ser definido:
server {
listen 80;
server_name "";
return 444;
}
Nesta configuração, o nome do servidor é definido como uma string vazia, que corresponde
a requisições sem o campo de cabeçalho Host
. Um código especial não-padrão 444
é então retornado, que fecha a conexão.
Combinando servidores virtuais baseados em nome e baseados em IP#
Vamos examinar uma configuração mais complexa onde alguns servidores virtuais escutam em endereços diferentes:
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
# ...
}
server {
listen 192.168.1.1:80;
server_name example.net www.example.net;
# ...
}
server {
listen 192.168.1.2:80;
server_name example.com www.example.com;
# ...
}
Nesta configuração, o Angie primeiro testa o endereço IP e a porta da
requisição contra as diretivas listen dos blocos server. Em seguida,
testa o campo de cabeçalho Host
da requisição contra as
entradas server_name dos blocos server que corresponderam ao endereço
IP e porta. Se o nome do servidor não for encontrado, a requisição será processada
pelo servidor padrão. Por exemplo, uma requisição para www.example.com
recebida na porta 192.168.1.1:80 será tratada pelo servidor padrão para essa
porta — ou seja, pelo primeiro servidor — já que www.example.com
não está definido
para esta porta.
Como mencionado anteriormente, um servidor padrão é uma propriedade da porta de escuta, e diferentes servidores padrão podem ser definidos para diferentes portas:
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
# ...
}
server {
listen 192.168.1.1:80 default_server;
server_name example.net www.example.net;
# ...
}
server {
listen 192.168.1.2:80 default_server;
server_name example.com www.example.com;
# ...
}
Escolhendo localizações#
Considere uma configuração simples de site PHP:
server {
listen 80;
server_name example.org www.example.org;
root /data/www;
location / {
index index.html index.php;
}
location ~* \.(gif|jpg|png)$ {
expires 30d;
}
location ~ \.php$ {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}
}
O Angie primeiro busca pela location
de prefixo mais específica dada por
strings literais, independentemente da ordem listada. Na configuração acima,
a única localização de prefixo é location /
, que corresponde a qualquer requisição e
será usada como último recurso. O Angie então verifica localizações definidas por
expressões regulares na ordem em que aparecem no arquivo de configuração. A
primeira expressão correspondente para a busca, e o Angie usará essa
location
. Se nenhuma expressão regular corresponder a uma requisição, o Angie usará
a location
de prefixo mais específica encontrada anteriormente.
Nota
Localizações de todos os tipos testam apenas a parte URI da linha de requisição, excluindo argumentos. Isso ocorre porque argumentos na string de consulta podem ser especificados de várias maneiras, por exemplo:
/index.php?user=john&page=1
/index.php?page=1&user=john
Além disso, strings de consulta podem conter qualquer número de parâmetros:
/index.php?page=1&something+else&user=john
Agora vamos ver como as requisições seriam processadas na configuração acima:
A requisição
/logo.gif
é primeiro correspondida pelo prefixolocation /
e depois pela expressão regular.(gif|jpg|png)$
. Portanto, é tratada pela última localização. Usando a diretivaroot /data/www
, a requisição é mapeada para o arquivo/data/www/logo.gif
, e o arquivo é enviado para o cliente.A requisição
/index.php
também é inicialmente correspondida pelo prefixolocation /
e depois pela expressão regular.(php)$
. Consequentemente, é tratada pela última localização, e a requisição é passada para um servidor FastCGI escutando emlocalhost:9000
. A diretiva fastcgi_param define o parâmetro FastCGISCRIPT_FILENAME
como/data/www/index.php
, e o servidor FastCGI executa o arquivo. A variável $document_root é definida com o valor da diretivaroot
, e a variável $fastcgi_script_name é definida com o URI da requisição, ou seja,/index.php
.A requisição
/about.html
é correspondida apenas pelo prefixolocation /
, então é tratada nesta localização. Usando a diretivaroot /data/www
, a requisição é mapeada para o arquivo/data/www/about.html
, e o arquivo é enviado para o cliente.
Tratar a requisição /
é mais complexo. Ela é correspondida apenas pelo prefixo
location /
, então é tratada por esta localização. A diretiva index então
testa a existência de arquivos de índice de acordo com seus parâmetros e a
diretiva root /data/www
. Se o arquivo /data/www/index.html
não
existir mas o arquivo /data/www/index.php
existir, a diretiva executa
um redirecionamento interno para /index.php
, e o Angie busca as localizações
novamente como se a requisição tivesse sido enviada por um cliente. Como mencionado anteriormente, a
requisição redirecionada será eventualmente tratada pelo servidor FastCGI.
Proxy e Balanceamento de Carga#
Um uso comum do Angie é configurá-lo como um servidor proxy. Neste papel, o Angie recebe requisições, as encaminha para os servidores proxy, recupera respostas desses servidores e envia as respostas de volta para os clientes.
Um servidor proxy simples:
server {
location / {
proxy_pass http://backend:8080;
}
A diretiva proxy_pass instrui o Angie a passar requisições do cliente para
o backend O Angie pode ser usado para rotear requisições para servidores FastCGI que executam aplicações
construídas com vários frameworks e linguagens de programação, como PHP. A configuração mais básica do Angie para trabalhar com um servidor FastCGI
envolve usar a diretiva fastcgi_pass em vez da
diretiva proxy_pass, junto com diretivas fastcgi_param para definir
parâmetros passados para o servidor FastCGI. Suponha que o servidor FastCGI seja
acessível em Esta configuração define um servidor que roteia todas as requisições, exceto aquelas para
imagens estáticas, para o servidor proxy operando em Para atualizar uma conexão de HTTP/1.1 para WebSocket, é usado o mecanismo de troca de protocolo disponível no HTTP/1.1. No entanto, há uma sutileza: como o cabeçalho O Angie implementa um modo especial de operação que permite configurar um túnel entre um cliente e um servidor proxy se o servidor proxy retornar uma resposta com código 101 (Switching Protocols), e o cliente solicitar uma troca de protocolo através do cabeçalho Como mencionado, cabeçalhos hop-by-hop, incluindo Um exemplo mais sofisticado demonstra como o valor do campo de cabeçalho Por padrão, a conexão será fechada se o servidor proxy não transmitir nenhum dado dentro de 60 segundos. Esse timeout pode ser aumentado usando a diretiva proxy_read_timeout. Alternativamente, o servidor proxy pode ser configurado para enviar periodicamente frames de ping WebSocket para redefinir o timeout e verificar se a conexão ainda está ativa. O balanceamento de carga entre múltiplas instâncias de aplicação é uma técnica amplamente usada para otimizar a utilização de recursos, maximizar o throughput, reduzir a latência e garantir configurações tolerantes a falhas. O Angie pode ser usado como um balanceador de carga HTTP altamente eficiente para distribuir tráfego para múltiplos servidores de aplicação, melhorando assim o desempenho, escalabilidade e confiabilidade de aplicações web. A configuração mais simples para balanceamento de carga com Angie pode parecer assim: No exemplo acima, três instâncias da mesma aplicação estão executando em backend:8080
(o servidor proxy). Existem muitas
diretivas adicionais disponíveis para configurar ainda mais uma conexão
proxy.Proxy FastCGI#
localhost:9000
. Em PHP, o parâmetro SCRIPT_FILENAME
é usado para determinar o nome do script, e o parâmetro QUERY_STRING
é usado para passar parâmetros de requisição. A configuração resultante seria:server {
location / {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
localhost:9000
via o
protocolo FastCGI.Proxy WebSocket#
Upgrade
é um cabeçalho hop-by-hop, ele não é passado do cliente para o servidor proxy. Com proxy direto, os clientes podem usar o método CONNECT para contornar esse problema. Essa abordagem não funciona com proxy reverso, pois os clientes não têm conhecimento de nenhum servidor proxy, e é necessário processamento especial no servidor proxy.Upgrade
na requisição.Upgrade
e Connection
, não são passados do cliente para o servidor proxy. Portanto, para que o servidor proxy tenha conhecimento da intenção do cliente de trocar para o protocolo WebSocket, esses cabeçalhos devem ser passados explicitamente:location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Connection
em uma requisição para o servidor proxy depende da presença do campo Upgrade
no cabeçalho da requisição do cliente:http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
...
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
Balanceamento de Carga#
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
srv1
até srv3
. Quando um método de balanceamento de carga não é explicitamente configurado, o padrão é round-robin. Outros mecanismos de balanceamento de carga suportados incluem: weight, least_conn, e ip_hash. A implementação de proxy reverso no Angie também suporta verificações de saúde do servidor in-band (ou passivas). Essas são configuradas usando as diretivas max_fails e fail_timeout dentro do bloco server no contexto upstream.
Logging#
Nota
Além das opções listadas aqui, você também pode habilitar o log de depuração.
Syslog#
As diretivas error_log e access_log suportam logging para syslog
. Os seguintes parâmetros são usados para configurar logging para syslog
:
| Especifica o endereço de um servidor |
| Define a facility para mensagens |
| Define o nível de severidade das mensagens |
| Define a tag para mensagens |
| Desabilita a adição do campo |
Exemplo de configuração syslog:
error_log syslog:server=192.168.1.1 debug;
access_log syslog:server=unix:/var/log/angie.sock,nohostname;
access_log syslog:server=[2001:db8::1]:12345,facility=local7,tag=angie,severity=info combined;
Nota
Entradas do syslog são reportadas no máximo uma vez por segundo para prevenir flooding.