Conexiones, sesiones, solicitudes, registros#
Mecanismos de procesamiento de conexiones#
Angie admite varios métodos de procesamiento de conexiones. La disponibilidad de un método específico depende de la plataforma que se esté utilizando. En plataformas que admiten múltiples métodos, Angie suele seleccionar automáticamente el método más eficiente. No obstante, si es necesario, se puede elegir explícitamente un método de procesamiento de conexiones usando la directiva use.
Los siguientes métodos de procesamiento de conexiones están disponibles:
Método | Descripción |
|---|---|
| Un método estándar. El módulo de soporte se crea automáticamente en plataformas que no disponen de métodos más eficientes. Las opciones de compilación |
| Un método estándar. El módulo de soporte se crea automáticamente en plataformas que no disponen de métodos más eficientes. Las opciones de compilación |
| Un método eficiente disponible en FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 y macOS. |
| Un método eficiente disponible en Linux 2.6+. |
| Un método eficiente disponible en Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ y Tru64 UNIX 5.1A+. |
| El método |
Procesamiento de solicitudes HTTP#
Una solicitud HTTP atraviesa una serie de fases, durante las cuales se realiza un tipo específico de procesamiento en cada fase.
| La fase inicial. En esta fase se invoca el módulo RealIP. |
| La fase en la que se procesan las directivas del módulo Rewrite, definidas dentro de un bloque |
| Una fase especial en la que se selecciona una location basada en la URI de la solicitud. |
| Similar a la fase |
| Una fase especial en la que la solicitud se redirige a una nueva ubicación, como en la fase |
| Durante esta fase, módulos estándar de Angie como Limit Req registran sus manejadores. |
| La fase en la que se verifica la autorización del cliente para realizar la solicitud, normalmente invocando módulos estándar de Angie como Auth Basic. |
| Una fase especial en la que se procesa la directiva satisfy any. |
| Las directivas de módulos estándar, como try_files y mirror, registran sus manejadores durante esta fase. |
| La fase en la que normalmente se genera la respuesta. Varios módulos estándar de Angie registran sus manejadores en esta etapa, incluyendo Index. Las directivas proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass y grpc_pass también se gestionan aquí. Los manejadores se invocan de forma secuencial hasta que uno de ellos genera la salida. |
| La fase final, en la que se registra la solicitud. Actualmente, solo el módulo Log registra su manejador en esta etapa para el registro de acceso. |
Procesamiento de sesiones TCP/UDP#
Una sesión TCP/UDP de un cliente atraviesa una serie de fases, durante las cuales se realiza un tipo específico de procesamiento en cada fase:
| La fase inicial tras aceptar una conexión del cliente. En esta fase se invoca el módulo RealIP. |
| Una fase preliminar para comprobar el acceso. Los módulos Set se invocan durante esta fase. |
| La fase en la que se limita el acceso del cliente antes del procesamiento real de datos. El módulo Access se invoca en esta etapa. |
| La fase en la que tiene lugar la terminación TLS/SSL. El módulo SSL se invoca durante esta fase. |
| La fase para leer los bytes iniciales de datos en el búfer de prelectura para permitir que módulos como SSL Preread analicen los datos antes del procesamiento. |
| Una fase obligatoria en la que realmente se procesan los datos, normalmente involucrando el módulo Return para enviar una respuesta al cliente. La directiva proxy_pass también se maneja aquí. |
| La fase final en la que se registra el resultado del procesamiento de la sesión del cliente. El módulo Log se invoca en esta fase. |
Selección de un servidor para una sesión#
Angie selecciona el bloque server para una sesión según la dirección
y el puerto que la aceptaron, exactamente igual que para las conexiones HTTP;
consulte Selección de un servidor por dirección y puerto para conocer
las reglas de coincidencia y el servidor predeterminado de un par. Los pares
TCP y UDP de un mismo puerto son independientes, cada uno con su propio
servidor predeterminado: un servidor con listen 9000 udp; nunca recibe
las conexiones TCP del puerto 9000.
Dentro del par coincidente, una sesión toma su nombre de servidor únicamente de la SNI: o bien el módulo SSL termina el TLS y obtiene el nombre a partir del protocolo de enlace, o bien el módulo SSL Preread lo lee sin terminar la conexión. Angie compara entonces ese nombre con las entradas server_name de los servidores que escuchan en el par; una sesión sin nombre SNI, o con un nombre que no coincide con ninguno de ellos, es gestionada por el servidor predeterminado del par.
Procesamiento de solicitudes#
Selección de servidor virtual#
Inicialmente, se crea una conexión dentro del contexto de un servidor predeterminado. El nombre del servidor puede determinarse en las siguientes etapas del procesamiento de la solicitud, cada una de las cuales está involucrada en la selección de la configuración del servidor:
Durante el protocolo de enlace SSL, de antemano, según el SNI.
Después de procesar la línea de solicitud.
Después de procesar el campo de cabecera
Host.
Si el nombre del servidor no se determina después de procesar la línea de solicitud o el campo de cabecera Host, Angie utilizará un nombre vacío como nombre de servidor.
En cada una de estas etapas, se pueden aplicar diferentes configuraciones de servidor. Por lo tanto, ciertas directivas deben especificarse con precaución:
En el caso de la directiva ssl_protocols, la lista de protocolos es establecida por la biblioteca OpenSSL antes de que se aplique la configuración del servidor según el nombre solicitado a través de SNI. Como resultado, los protocolos solo deben especificarse para el servidor predeterminado.
Las directivas client_header_buffer_size y merge_slashes se aplican antes de leer la línea de solicitud. Por lo tanto, estas directivas utilizan la configuración del servidor predeterminado o la configuración del servidor elegida por SNI.
En el caso de las directivas ignore_invalid_headers, large_client_header_buffers y underscores_in_headers, que están involucradas en el procesamiento de los campos de cabecera de solicitud, la configuración del servidor depende adicionalmente de si se actualizó según la línea de solicitud o el campo de cabecera
Host.Una respuesta de error se gestiona mediante la directiva error_page en el servidor que está procesando actualmente la solicitud.
Servidores virtuales basados en nombres#
Angie determina primero qué servidor debe manejar la solicitud. Considere una configuración simple donde los tres servidores virtuales escuchan en el puerto 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;
# ...
}
En esta configuración, Angie determina qué servidor debe manejar la solicitud
basándose únicamente en el campo de cabecera Host. Si el valor de esta
cabecera no coincide con ningún nombre de servidor, Angie enruta la solicitud
al servidor predeterminado del par *:80. En la configuración anterior,
el servidor predeterminado es el primero — el comportamiento predeterminado
estándar de Angie. También puede especificarse explícitamente qué servidor
debe ser el predeterminado mediante el parámetro default_server en la
directiva listen:
server {
listen 80 default_server;
server_name example.net www.example.net;
# ...
}
Nota
Tenga en cuenta que el servidor predeterminado es una propiedad del par address:port, no del nombre del servidor.
Nombres internacionalizados#
Los nombres de dominio internacionalizados (IDN) deberían especificarse utilizando una representación ASCII (Punycode) en la directiva server_name (nombre del servidor):
server {
listen 80;
server_name xn--e1afmkfd.xn--80akhbyknj4f; # пример.испытание
# ...
}
Prevención de solicitudes con nombres de servidor indefinidos#
Si no se deben permitir solicitudes sin el campo de cabecera Host, se puede definir un
servidor que simplemente descarte esas solicitudes:
server {
listen 80;
server_name "";
return 444;
}
En esta configuración, el nombre del servidor se establece como una cadena vacía, que coincide
con las solicitudes sin el campo de cabecera Host. A continuación se devuelve un código especial no estándar 444,
que cierra la conexión.
Selección de un servidor por dirección y puerto#
Angie selecciona el bloque server para una conexión en dos pasos: primero por la dirección y el puerto que aceptaron la conexión, y después por el nombre.
Las directivas listen de la configuración definen los pares
address:port en los que Angie acepta conexiones. Los pares en puertos
distintos, en familias de direcciones distintas o en transportes distintos
nunca compiten por una conexión: un socket de escucha quic es UDP,
por lo que tiene su propio par incluso en un puerto que también tiene sockets
de escucha TCP. Cuando llega una conexión, Angie compara la dirección que la
aceptó con los pares de ese puerto: una dirección explícita tiene prioridad,
y *:port es el último recurso. Por eso, un servidor que escucha en
*:port tiene su propio par y no sustituye a los servidores de las
direcciones explícitas de ese puerto. El par coincidente determina el resto
de la selección: qué servidores comprueba Angie por nombre, cuál de ellos es
el predeterminado, y cuáles de los parámetros ssl, http2,
quic y proxy_protocol se aplican a la conexión. Una ruta de
socket de dominio UNIX es un par en el mismo sentido: tiene su propio
servidor predeterminado y su propio conjunto de nombres de servidor.
A continuación, Angie compara el campo de cabecera Host con las
entradas server_name de los servidores cuyas directivas listen
nombran el par coincidente; los servidores que escuchan en otra dirección del
mismo puerto, incluido *:port, nunca se consultan. Si ningún nombre
coincide, el servidor predeterminado del par gestiona la solicitud: el primer
servidor de la configuración que nombra el par, salvo que otro servidor lo
nombre con el parámetro default_server. Una solicitud que no lleva
nombre de host se compara con el nombre de servidor vacío, como se describe
en Prevención de solicitudes con nombres de servidor indefinidos; sobre HTTP/2 y HTTP/3 esa solicitud se rechaza antes
de seleccionar un servidor. Angie rechaza una configuración en la que dos
servidores reclaman el mismo par como predeterminado, informando
a duplicate default server for address:port.
En una conexión TLS, Angie inicia el protocolo de enlace en la configuración del servidor predeterminado del par, por lo que su ssl_certificate es el que se ofrece a menos que el nombre SNI coincida con otro servidor del mismo par; consulte Servidores HTTPS basados en nombres para servir varios nombres en un mismo par.
En la siguiente configuración, cuatro servidores escuchan en el puerto 80 —
dos en 198.51.100.1, uno en 198.51.100.2 y uno en *:80:
server {
listen 198.51.100.1:80;
server_name example.org www.example.org;
# ...
}
server {
listen 198.51.100.1:80;
server_name example.net www.example.net;
# ...
}
server {
listen 198.51.100.2:80;
server_name example.com www.example.com;
# ...
}
server {
listen 80;
server_name www.example.test;
# ...
}
Una conexión aceptada en 198.51.100.1:80 coincide con ese par, por lo que
Angie compara el campo de cabecera Host solo con los dos primeros
servidores. Por eso, una solicitud de www.example.test es gestionada
por el primero de ellos, el servidor predeterminado de 198.51.100.1:80,
aunque el cuarto servidor tenga ese nombre; lo mismo ocurre con
www.example.com, que pertenece al par 198.51.100.2:80. El cuarto
servidor gestiona únicamente las conexiones aceptadas en direcciones del
puerto 80 que ninguna otra directiva listen nombra.
Cada par tiene su propio servidor predeterminado, y default_server
lo designa para el par nombrado por esa misma directiva listen:
server {
listen 198.51.100.1:80;
server_name example.org www.example.org;
# ...
}
server {
listen 198.51.100.1:80 default_server;
server_name example.net www.example.net;
# ...
}
server {
listen 198.51.100.2:80 default_server;
server_name example.com www.example.com;
# ...
}
Añadir listen 80 default_server; a otro servidor establecería el
predeterminado solo para *:80; el predeterminado de 198.51.100.1:80
seguiría siendo el servidor que lleva default_server ahí.
Elección de ubicaciones#
Consideremos una configuración simple de un sitio web 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;
}
}
Angie primero busca la location de prefijo más específica dada por cadenas literales, independientemente del orden en que estén listadas. En la configuración anterior, la única ubicación de prefijo es location /, que coincide con cualquier solicitud y se utilizará como último recurso. Luego, Angie comprueba las ubicaciones definidas por expresiones regulares en el orden en que aparecen en el archivo de configuración. La primera expresión coincidente detiene la búsqueda, y Angie utilizará esa location. Si ninguna expresión regular coincide con una solicitud, Angie utilizará la location de prefijo más específica encontrada anteriormente.
Nota
Las ubicaciones de todos los tipos solo prueban la parte URI de la línea de solicitud, excluyendo los argumentos. Esto se debe a que los argumentos en la cadena de consulta pueden especificarse de varias maneras, por ejemplo:
/index.php?user=john&page=1/index.php?page=1&user=john
Además, las cadenas de consulta pueden contener cualquier número de parámetros:
/index.php?page=1&something+else&user=john
Ahora veamos cómo se procesarían las solicitudes en la configuración anterior:
La solicitud
/logo.gifprimero coincide con el prefijolocation /y luego con la expresión regular.(gif|jpg|png)$. Por lo tanto, es manejada por la última ubicación. Usando la directivaroot /data/www, la solicitud se asigna al archivo/data/www/logo.gif, y el archivo se envía al cliente.La solicitud
/index.phptambién coincide inicialmente con el prefijolocation /y luego con la expresión regular.(php)$. En consecuencia, es manejada por esta última ubicación, y la solicitud se pasa a un servidor FastCGI que escucha enlocalhost:9000. La directiva fastcgi_param establece el parámetro FastCGISCRIPT_FILENAMEa/data/www/index.php, y el servidor FastCGI ejecuta el archivo. La variable $document_root se establece con el valor de la directivaroot, y la variable $fastcgi_script_name se establece con el URI de la solicitud, es decir,/index.php.La solicitud
/about.htmlsolo coincide con el prefijolocation /, por lo que se maneja en esta ubicación. Usando la directivaroot /data/www, la solicitud se asigna al archivo/data/www/about.html, y el archivo se envía al cliente.
El manejo de la solicitud / es más complejo. Solo coincide con el prefijo
location /, por lo que se maneja en esta ubicación. La directiva index entonces
comprueba la existencia de archivos de índice según sus parámetros y la
directiva root /data/www. Si el archivo /data/www/index.html no existe pero el archivo /data/www/index.php sí, la directiva realiza
una redirección interna a /index.php, y Angie busca las ubicaciones nuevamente como si la solicitud hubiera sido enviada por un cliente. Como se mencionó anteriormente, la solicitud redirigida finalmente será manejada por el servidor FastCGI.
Los ejemplos anteriores asignan una solicitud a un archivo a través de la directiva root, pero la correspondencia completa implica varias directivas que actúan conjuntamente. Una vez seleccionado el location coincidente, Angie asigna el $uri normalizado de la solicitud a una ruta del sistema de archivos: la directiva root añade el URI completo a su valor, mientras que la directiva alias reemplaza el prefijo de la ubicación coincidente. La directiva try_files comprueba entonces la existencia de archivos candidatos en esa ruta; si no existe ninguno, su último parámetro desencadena una redirección interna, y Angie vuelve a buscar en las ubicaciones con el nuevo $uri, igual que en la redirección al archivo índice mencionada anteriormente.
Para la misma solicitud /images/top.gif, las dos ubicaciones siguientes la
resuelven al mismo archivo, /data/w3/images/top.gif:
location /images/ {
root /data/w3; # añade: /data/w3 + /images/top.gif
}
location /images/ {
alias /data/w3/images/; # reemplaza: /images/ -> /data/w3/images/, luego top.gif
}
Con alias, el prefijo coincidente se elimina por su longitud, por lo que las
barras finales de la ubicación y del valor de alias deben ser consistentes. Si se
eliminara la barra final de la ruta del alias anterior, el resultado sería
/data/w3/imagestop.gif.
Proxy y balanceo de carga#
Uno de los usos más comunes de Angie es configurarlo como servidor proxy. En este rol, Angie recibe solicitudes, las reenvía a los servidores proxied, obtiene las respuestas de esos servidores y las envía de vuelta a los clientes.
Un servidor proxy simple:
server {
location / {
proxy_pass http://backend:8080;
}
La directiva proxy_pass indica a Angie que pase las solicitudes del cliente al
backend Angie puede usarse para enrutar solicitudes a servidores FastCGI que ejecutan aplicaciones
desarrolladas con varios marcos y lenguajes de programación, como PHP. La configuración más básica de Angie para trabajar con un servidor FastCGI
involucra usar la directiva fastcgi_pass en lugar de la
directiva proxy_pass, junto con directivas fastcgi_param para establecer
parámetros pasados al servidor FastCGI. Supongamos que el servidor FastCGI es
accesible en Esta configuración establece un servidor que enruta todas las solicitudes, excepto aquellas para
imágenes estáticas, al servidor proxied que opera en Para actualizar una conexión de HTTP/1.1 a WebSocket, se utiliza el mecanismo de cambio de protocolo disponible en HTTP/1.1. Sin embargo, existe una sutileza: dado que la cabecera Angie implementa un modo especial de operación que permite establecer un túnel
entre un cliente y un servidor proxy si el servidor proxy devuelve una respuesta
con código 101 (Switching Protocols), y el cliente solicita un cambio de protocolo
mediante la cabecera Como se mencionó, las cabeceras salto a salto, incluyendo Un ejemplo más sofisticado demuestra cómo el valor del
campo de cabecera Por defecto, la conexión se cerrará si el servidor proxy no
transmite ningún dato en 60 segundos. Este tiempo de espera puede aumentarse usando la
directiva proxy_read_timeout. Alternativamente, el servidor proxy puede
configurarse para enviar periódicamente tramas de ping de WebSocket para restablecer el tiempo de espera y
comprobar si la conexión sigue activa. Angie puede actuar como balanceador de carga, distribuyendo las solicitudes entre
un grupo de servidores upstream y eligiendo el servidor mediante uno de varios
métodos de balanceo. Consulte Balanceo de carga para saber cómo elegir un
método, qué significa el peso de un servidor para cada uno de ellos y cómo se
gestionan los fallos de servidor.backend:8080 (el servidor proxied). Hay muchas directivas adicionales disponibles para configurar aún más una conexión proxy.Proxy FastCGI#
localhost:9000. En PHP, el parámetro SCRIPT_FILENAME
se utiliza para determinar el nombre del script, y el parámetro QUERY_STRING
se utiliza para pasar los parámetros de la solicitud. La configuración resultante sería: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 a través del
protocolo FastCGI.Proxy de WebSocket#
Upgrade es una cabecera salto a salto, no se
pasa del cliente al servidor proxy. Con el proxy directo, los clientes
pueden usar el método CONNECT para evitar este problema. Este enfoque no funciona
con el proxy inverso, ya que los clientes no son conscientes de ningún servidor proxy, y se requiere
un procesamiento especial en el servidor proxy.Upgrade en la solicitud.Upgrade y
Connection, no se pasan del cliente al servidor proxy.
Por lo tanto, para que el servidor proxy sea consciente de la intención del cliente de
cambiar al protocolo WebSocket, estas cabeceras deben pasarse explícitamente:location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Connection en una solicitud al servidor proxy depende de
la presencia del campo Upgrade en la cabecera de solicitud del 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;
}
}
}
Balanceo de carga#
Registro#
Nota
Además de las opciones enumeradas aquí, también puede habilitar el registro de depuración.
Syslog#
Las directivas error_log y access_log admiten el registro en
syslog. Los siguientes parámetros se utilizan para configurar el registro en
syslog:
| Especifica la dirección de un servidor |
| Establece la facilidad para los mensajes de |
| Define el nivel de severidad de los mensajes de |
| Establece la etiqueta para los mensajes de |
| Desactiva la adición del campo |
Ejemplo de configuración 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;