---
title: "Conocimiento de NGINX utilizado en OpenResty - API7.ai"
description: "Nginx ofrece el modelo Master-Worker y las fases de ejecución de solicitudes. Al leer esta publicación, podrás comprender mejor los conceptos básicos de Nginx."
url: "https://api7.ai/es/learning-center/openresty/knowledge-of-nginx-used-in-openresty"
---

# Conocimiento de NGINX utilizado en OpenResty

API7.ai

September 17, 2022

[OpenResty (NGINX + Lua)](https://api7.ai/learning-center/openresty)

A través del [post anterior](https://api7.ai/learning-center/openresty/how-to-manage-openresty-packages/), ya tienes un conocimiento general de OpenResty. En los siguientes artículos, te guiaré a través de los dos pilares de OpenResty: NGINX y LuaJIT, y podrás aprender mejor OpenResty dominando estos conceptos básicos.

Hoy comenzaré con NGINX, y aquí solo introduciré algunos conceptos básicos de NGINX que pueden ser utilizados en OpenResty, que es solo un pequeño subconjunto de NGINX.

En cuanto a la configuración, en el desarrollo de OpenResty, debemos prestar atención a los siguientes puntos.

- Configurar `nginx.conf` lo menos posible.
- Evitar el uso de combinaciones de múltiples directivas como `if`, `set`, `rewrite`, etc.
- No usar configuraciones, variables y módulos de NGINX cuando se pueda resolver con código Lua.

Estos métodos maximizarán la legibilidad, mantenibilidad y extensibilidad. La siguiente configuración de NGINX es un ejemplo típico de mal uso de la configuración como código.

```
location ~ ^/mobile/(web/app.htm) {
    set $type $1;
    set $orig_args $args;
    if ( $http_user_Agent ~ "(iPhone|iPad|Android)" ) {
        rewrite  ^/mobile/(.*) http://touch.foo.com/mobile/$1 last;
    }
    proxy_pass http://foo.com/$type?$orig_args;
}
```

Esto es lo que debemos evitar al desarrollar con OpenResty.

## Configuración de NGINX

NGINX controla su comportamiento a través de archivos de configuración, que pueden considerarse como un DSL simple. NGINX lee la configuración cuando el proceso se inicia y la carga en memoria. Si modificas el archivo de configuración, necesitarás reiniciar o recargar NGINX y esperar a que NGINX lea nuevamente el archivo de configuración para que la nueva configuración surta efecto. Solo la versión comercial de NGINX proporciona algunas de estas capacidades dinámicas en tiempo de ejecución, en forma de APIs.

Comencemos con la siguiente configuración, que es muy simple.

```
worker_processes auto;

pid logs/nginx.pid;
error_log logs/error.log notice;

worker_rlimit_nofile 65535;

events {
    worker_connections 16384;
}

http {
    server {
        listen 80;
        listen 443 ssl;

        location / {
            proxy_pass https://foo.com;
        }
    }
}

stream {
    server {
        listen 53 udp;
    }
}
```

Sin embargo, incluso estas configuraciones simples involucran algunos conceptos fundamentales.

Primero, cada directiva tiene su **contexto**, que es su alcance en el archivo de configuración de NGINX.

El nivel superior es `main`, que contiene algunas instrucciones que no están relacionadas con el negocio específico, como `worker_processes`, `pid` y `error_log`, que forman parte del contexto `main`. Además, existe una relación jerárquica entre los contextos. Por ejemplo, el contexto de `location` es `server`, el contexto de `server` es `http`, y el contexto de `http` es `main`.

Las directivas no pueden ejecutarse en el contexto incorrecto. NGINX verificará si `nginx.conf` es legal cuando se inicie. Por ejemplo, si cambiamos `listen 80`; del contexto `server` al contexto `main` e iniciamos el servicio NGINX, veremos un error como este:

```
"listen" directive is not allowed here ......
```

En segundo lugar, NGINX puede manejar no solo solicitudes HTTP y tráfico HTTPS, sino también tráfico UDP y TCP. El L7 está en HTTP y el L4 está en Stream. En OpenResty, `lua-nginx-module` y `stream-lua-nginx-module` corresponden a estos dos, respectivamente.

Algo a tener en cuenta aquí es que OpenResty no admite todas las funciones de NGINX, y debes ver la versión de OpenResty. La versión de OpenResty es consistente con NGINX, lo que facilita su identificación.

Las directivas de configuración involucradas en `nginx.conf` anteriormente están en los módulos centrales de NGINX [ngx\_core\_module](https://nginx.org/en/docs/ngx_core_module.html,), [ngx\_http\_core\_module](https://nginx.org/en/docs/http/ngx_http_core_module.html), y [ngx\_stream\_core\_module](https://nginx.org/en/docs/stream/ngx_stream_core_module.html), a los que puedes hacer clic para ver la documentación específica.

## Modo MASTER-WORKER

Después de entender el archivo de configuración, veamos el modo multiproceso de NGINX (como se muestra en la figura a continuación). Como puedes ver, cuando NGINX se inicia, habrá un proceso `Master` y múltiples procesos `Worker` (o solo un proceso Worker, dependiendo de cómo lo configures).

![Modo Worker de NGINX](https://static.api7.ai/2022/09/17/63257daada6b2.png?imageMogr2/format/webp)

En primer lugar, el proceso `Master`, como su nombre lo indica, desempeña el papel de "gerente" y no es responsable de manejar las solicitudes de los clientes. Gestiona el proceso `Worker`, incluyendo recibir señales del administrador y monitorear el estado de los `Worker`s. Cuando un proceso `Worker` sale de manera anormal, el proceso `Master` reiniciará un nuevo proceso `Worker`.

Los procesos `Worker` son los "empleados reales" que manejan las solicitudes de los clientes. Son bifurcados desde el proceso `Master` y son independientes entre sí. Este modelo multiproceso es mucho más avanzado que el modelo multihilo de Apache, sin bloqueos entre hilos y fácil de depurar. Incluso si un proceso se bloquea y sale, generalmente no afecta el trabajo de los otros procesos `Worker`.

OpenResty agrega un agente privilegiado único al modelo Master-Worker de NGINX. Este proceso no escucha en ningún puerto y tiene los mismos privilegios que el proceso `Master` de NGINX, por lo que puede realizar algunas tareas que requieren altos privilegios, como algunas operaciones de escritura en archivos de disco local.

Si el proceso privilegiado funciona con el mecanismo de actualización en caliente binaria de NGINX, OpenResty puede implementar la actualización completa del binario sobre la marcha sin depender de programas externos.

Reducir la dependencia de programas externos y tratar de resolver problemas dentro del proceso de OpenResty facilita la implementación, reduce los costos de operación y mantenimiento, y disminuye la probabilidad de errores en el programa. El proceso privilegiado y `ngx.pipe` en OpenResty están destinados a este propósito.

## Fases de Ejecución

Las fases de ejecución también son una característica esencial de NGINX y están estrechamente relacionadas con la implementación específica de OpenResty. NGINX tiene 11 fases de ejecución, que podemos ver en el código fuente de `ngx_http_core_module.h`:

```
typedef enum {
    NGX_HTTP_POST_READ_PHASE = 0,

    NGX_HTTP_SERVER_REWRITE_PHASE,

    NGX_HTTP_FIND_CONFIG_PHASE,
    NGX_HTTP_REWRITE_PHASE,
    NGX_HTTP_POST_REWRITE_PHASE,

    NGX_HTTP_PREACCESS_PHASE,

    NGX_HTTP_ACCESS_PHASE,
    NGX_HTTP_POST_ACCESS_PHASE,

    NGX_HTTP_PRECONTENT_PHASE,

    NGX_HTTP_CONTENT_PHASE,

    NGX_HTTP_LOG_PHASE
} ngx_http_phases;
```

Si deseas aprender más sobre el papel de estas 11 fases, puedes leer la documentación de NGINX, por lo que no entraré en detalles aquí.

Coincidentemente, OpenResty también tiene 11 directivas `*_by_lua` relacionadas con la fase de NGINX, como se muestra en la figura a continuación (de la documentación de `lua-nginx-module`).

![Orden de las Directivas del Módulo Lua NGINX](https://static.api7.ai/2022/09/17/63257f1a69d8f.png?imageMogr2/format/webp)

`init_by_lua` se ejecuta solo cuando se crea el proceso `Master`, y `init_worker_by_lua` se ejecuta solo cuando se crea cada proceso `Worker`. Las otras directivas `*_by_lua` son activadas por solicitudes de clientes y se ejecutan repetidamente.

Por lo tanto, durante la fase `init_by_lua`, podemos precargar módulos Lua y datos de solo lectura públicos para aprovechar la función COW (copy on write) del sistema operativo y ahorrar memoria.

La mayoría de las operaciones se pueden realizar dentro de `content_by_lua`, pero recomendaría dividirlas según diferentes funciones, como las siguientes.

- `set_by_lua`: establecer variables.
- `rewrite_by_lua`: reenvío, redirección, etc.
- `access_by_lua`: acceso, permisos, etc.
- `content_by_lua`: generar contenido de respuesta.
- `header_filter_by_lua`: procesamiento de filtrado de encabezados de respuesta.
- `body_filter_by_lua`: procesamiento de filtrado del cuerpo de la respuesta.
- `log_by_lua`: registro.

Permíteme darte un ejemplo para mostrar los beneficios de dividirlo de esta manera. Supongamos que se proporcionan muchas APIs en texto plano externamente, y ahora necesitamos agregar lógica personalizada de cifrado y descifrado. Entonces, ¿necesitamos cambiar el código de todas las APIs?

```
location /mixed {
    content_by_lua '...';
}
```

Por supuesto que no. Usando la característica de fases, podemos descifrar en la fase `access` y cifrar en la fase `body filter` sin hacer ningún cambio en el código de la fase `content` original.

```
location /mixed {
    access_by_lua '...';
    content_by_lua '...';
    body_filter_by_lua '...';
}
```

## Actualización en Caliente del Binario de NGINX

Finalmente, permíteme explicar brevemente la actualización en caliente del binario de NGINX. Sabemos que después de modificar el archivo de configuración de NGINX, necesitas recargarlo para que surta efecto. Pero cuando NGINX se actualiza a sí mismo, puede hacerlo en caliente. Esto puede parecer poner el carro delante del caballo, pero es comprensible dado que NGINX comenzó con balanceo de carga estático tradicional, proxy inverso y almacenamiento en caché de archivos.

La actualización en caliente se realiza enviando señales `USR2` y `WINCH` al proceso `Master` antiguo. Para estos dos pasos, el primero inicia el nuevo proceso `Master`; el segundo cierra gradualmente el proceso `Worker`.

Después de estos dos pasos, el nuevo `Master` y el nuevo `Worker` se inician. En este punto, el `Master` antiguo no se cierra. La razón para no cerrarlo es simple: si necesitas retroceder, aún puedes enviar señales `HUP` al `Master` antiguo. Por supuesto, si has determinado que no necesitas retroceder, puedes enviar una señal `KILL` al `Master` antiguo para que se cierre.

Eso es todo, y la actualización en caliente del binario de NGINX está completa.

Si deseas obtener información más detallada sobre esto, puedes consultar la documentación oficial para seguir aprendiendo.

## Resumen

En general, lo que usas en OpenResty son los conceptos básicos de NGINX, principalmente relacionados con la configuración, procesos maestro-esclavo, fases de ejecución, etc. Las otras cosas que se pueden resolver con código Lua se resuelven con código tanto como sea posible, en lugar de usar módulos y configuraciones de NGINX, lo cual es un cambio de mentalidad al aprender OpenResty.

Finalmente, te dejo una pregunta abierta: Nginx oficialmente admite NJS, lo que significa que puedes escribir JS para controlar parte de la lógica de NGINX, similar a OpenResty. ¿Qué opinas sobre esto? Bienvenido a compartir este artículo.

Share article link

Share

Related Posts

[![Preguntas frecuentes de OpenResty | Cómo se utiliza OpenResty en la práctica](https://static.api7.ai/uploads/2023/02/12/jbv9M0zi_Hello%20World%20in%20OpenResty%20%283%29.png)](https://api7.ai/learning-center/openresty/faq-5)

## [Preguntas frecuentes de OpenResty | Cómo se utiliza OpenResty en la práctica](https://api7.ai/learning-center/openresty/faq-5)

[![Parte 3: Cómo construir una API Gateway para Microservicios usando OpenResty](https://static.api7.ai/uploads/2023/02/07/3XJXY9Jy_45.png)](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

## [Parte 3: Cómo construir una API Gateway para Microservicios usando OpenResty](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

Table of Contents

- [Configuración de NGINX](#configuraci%C3%B3n-de-nginx)
- [Modo MASTER-WORKER](#modo-master-worker)
- [Fases de Ejecución](#fases-de-ejecuci%C3%B3n)
- [Actualización en Caliente del Binario de NGINX](#actualizaci%C3%B3n-en-caliente-del-binario-de-nginx)
- [Resumen](#resumen)
