---
title: "FAQ de OpenResty | Permisos de Proceso Privilegiado, Fase de Ejecución y más - API7.ai"
description: "El FAQ de NGINX + Lua (OpenResty) responde preguntas sobre los permisos de procesos privilegiados, la fase y depuración, la práctica de ngx.exit, las variables y las condiciones de carrera."
url: "https://api7.ai/es/learning-center/openresty/faq-2"
---

# FAQ de OpenResty | Permisos de Proceso Privilegiado, Fase de Ejecución y más

API7.ai

November 11, 2022

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

Este artículo contiene seis preguntas frecuentes:

## 1. Permisos de Procesos Privilegiados

P: ¿Qué es un proceso privilegiado? ¿Cómo podría un usuario no privilegiado obtener permisos de `root`? ¿Puedes presentar algunos escenarios de procesos privilegiados?

R: Los permisos del proceso privilegiado son los mismos que los del proceso `master`. Si inicias OpenResty como un usuario no privilegiado, entonces el proceso `master` hereda los privilegios del usuario, lo que significa que el "proceso privilegiado" no tiene derechos en este momento.

Es fácil entender que no hay privilegios de root cuando un usuario normal inicia un proceso.

En cuanto a los escenarios de uso del proceso privilegiado, generalmente lo utilizamos para tareas que requieren altos privilegios, como la limpieza de registros y el reinicio de OpenResty. Sin embargo, ten cuidado de no usar el proceso privilegiado para ejecutar tareas del proceso worker debido a los riesgos de seguridad.

Un desarrollador ejecuta todas las tareas de `timer` en el proceso privilegiado. ¿Por qué lo hace? Porque solo hay un proceso privilegiado, de esta manera, el `timer` no se inicia repetidamente.

El desarrollador es "inteligente" ya que logró el objetivo sin usar `worker.id`. Sin embargo, no olvides que es muy peligroso si la tarea de `timer` depende de la entrada del cliente.

## 2. Fases y Depuración

P: Después de ejecutar `ngx.say('hello')`, ¿OpenResty responderá directamente al cliente después de ejecutar el resto de la lógica en la fase actual? Es decir, ¿no continuará ejecutando las fases posteriores?

R: No es así. Podemos observar su fase de ejecución:

![image](https://static.api7.ai/2022/10/28/635b7fad958fc.webp?imageMogr2/format/webp)

Puedes probar `ngx.say` en la fase `content` primero, luego usar `ngx.log` en la fase `log` o `body filter` para imprimir el registro.

En artículos anteriores, no mencioné específicamente el problema de depurar código en OpenResty, lo cual puede confundir a los desarrolladores.

No hay características avanzadas para depurar código en OpenResty, como puntos de interrupción (hay algunos complementos de pago, pero no los he usado), y solo puedes usar `ngx.say` y `ngx.log` para ver la salida. Así es como todos los desarrolladores que conozco hacen su depuración, incluidos los autores y colaboradores de OpenResty. Por lo tanto, necesitas casos de prueba robustos y registros de depuración como garantía.

## 3. La Práctica de `ngx.exit`

P: En uno de los artículos anteriores, hay una descripción: el código de estado HTTP de OpenResty tiene una constante especial `ngx.OK`. Después de ejecutar `ngx.exit(ngx.OK)`, la solicitud sale de la fase actual y pasa a la siguiente fase en lugar de regresar directamente al cliente.

Recuerdo que `ngx.OK` no debería considerarse como un código de estado HTTP, su valor es `0`. Mi entendimiento es:

- Después de ejecutar `ngx.exit(ngx.OK)`, `ngx.exit(ngx.ERROR)` o `ngx.exit(ngx.DECLINED)`, la solicitud sale de la fase actual y pasa a la siguiente fase.
- Cuando `ngx.exit(ngx.HTTP_*)` toma los diversos códigos de estado HTTP de `ngx.HTTP_*` como parámetro, responderá directamente al cliente.

No sé si mi entendimiento es correcto.

R: Respecto a tu primera pregunta, `ngx.ok` no es un código de estado HTTP, sino una constante en OpenResty con un valor de `0`.

En cuanto a la segunda pregunta, la documentación oficial de `ngx.exit` puede ser la respuesta exacta:

1. Cuando status >= 200 (es decir, ngx.HTTP\_OK y superior), interrumpirá la ejecución de la solicitud actual y devolverá el código de estado a nginx.
2. Cuando status == 0 (es decir, ngx.OK), solo saldrá del manejador de la fase actual (o el manejador de contenido si se usa la directiva content\_by\_lua\*) y continuará ejecutando las fases posteriores (si las hay) para la solicitud actual.

Sin embargo, la documentación no menciona cómo OpenResty maneja `ngx.exit(ngx.ERROR)` y `ngx.exit(ngx.DECLINED)`. Podemos hacer una prueba de la siguiente manera:

```
location /lua {
    rewrite_by_lua "ngx.exit(ngx.ERROR)";
    echo hello;
}
```

Al visitar este `location`, puedes ver que el código de respuesta HTTP está vacío, el cuerpo de la respuesta también está vacío, y no pasa a la siguiente fase de ejecución.

A medida que te adentras más en el proceso de aprendizaje de OpenResty, en algún momento te darás cuenta de que ni la documentación ni los casos de prueba pueden responder tus preguntas. En este punto, necesitas construir tus propios casos de prueba para verificar tus ideas. Puedes hacerlo manualmente o agregar las pruebas al conjunto de casos de prueba construido por `test::nginx`.

## 4. Variables y Condición de Carrera

P: Como se mencionó anteriormente, el alcance de la variable `ngx.var` está entre los módulos `nginx C` y `lua-nginx-module`.

1. No entiendo muy bien esto. Desde la perspectiva de la solicitud, ¿significa una sola solicitud en un proceso worker?
2. Mi entendimiento es que cuando manipulamos variables dentro de un módulo. Si hay una operación de bloqueo entre dos operaciones, puede existir una condición de carrera. Entonces, si no hay una operación de bloqueo entre dos operaciones, y resulta que el proceso actual entra en la cola de listos cuando se agota el tiempo de CPU, ¿es posible que exista una condición de carrera?

R: Veamos estas preguntas.

Primero, respecto a la variable `ngx.var`, tu entendimiento es correcto. El ciclo de vida de `ngx.var` es el mismo que el de la solicitud, y desaparece cuando la solicitud termina. Pero su ventaja es que los datos pueden pasarse en módulos C y código Lua, lo cual no es posible de otras maneras.

Segundo, siempre que haya una operación de `yield` entre dos operaciones, puede haber una condición de carrera en lugar de una operación de bloqueo. No hay condición de carrera cuando hay una operación de bloqueo. En otras palabras, siempre que no des la iniciativa al bucle de eventos de NGINX, no habrá condición de carrera.

## 5. El `shared dict` No Necesita Bloqueos

P: Si múltiples workers almacenan datos concurrentemente, ¿es necesario agregar bloqueos?

Por ejemplo:

```
resty --shdict 'dogs 10m' -e 'local dogs = ngx.shared.dogs
local lock= ngx.xxxx.lock
lock.lock()
 dogs:set("Jim", 8)
lock.unlock()
 local v = dogs:get("Jim")
 ngx.say(v)
 '
```

R: No necesitas agregar un bloqueo aquí porque, sin importar si es una operación `get` o `set`, la operación de `shared dict` es atómica. OpenResty ya ha considerado este tipo de manejo similar a bloqueos.

## 6. Operaciones de Tiempo en OpenResty

P: Usando `ngx.now()` para obtener el tiempo, ¿ocurre esto en la fase de restauración de la función `resume`?

R: NGINX está diseñado con el rendimiento como prioridad y almacena en caché el tiempo. Podemos verificar esto mediante el código fuente de `ngx.now`:

```
static int
ngx_http_lua_ngx_now(lua_State *L)
{
    ngx_time_t              *tp;

    tp = ngx_timeofday();

    lua_pushnumber(L, (lua_Number) (tp->sec + tp->msec / 1000.0L));

    return 1;
}
```

Como puedes ver, detrás de la función `ngx.now()` que obtiene el tiempo actual está la función `ngx_timeofday` de NGINX. La función `ngx_timeofday` es una definición de macro:

```
#define ngx_timeofday()      (ngx_time_t *) ngx_cached_time
```

Aquí el valor de `ngx_cached_time` solo se actualizará en la función `ngx_time_update`.

Entonces, la pregunta se convierte en "¿cuándo se llama a la función `ngx_time_update`?" Si lo rastreas en el código fuente de NGINX, verás que las llamadas a `ngx_time_update` ocurren en el bucle de eventos, entonces este problema se resuelve.

## Resumen

También deberías poder darte cuenta a través de estas preguntas, el beneficio de los proyectos de código abierto es que puedes seguir las pistas y buscar respuestas en el código fuente, lo que te dará una sensación de resolver el caso.

Finalmente, espero que a través de la comunicación y las preguntas y respuestas, pueda ayudarte a convertir lo que aprendes en lo que obtienes. También te invito a compartir este artículo, y juntos nos comunicaremos y mejoraremos.

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

- [1. Permisos de Procesos Privilegiados](#1-permisos-de-procesos-privilegiados)
- [2. Fases y Depuración](#2-fases-y-depuraci%C3%B3n)
- [3. La Práctica de `ngx.exit`](#3-la-pr%C3%A1ctica-de-ngxexit)
- [4. Variables y Condición de Carrera](#4-variables-y-condici%C3%B3n-de-carrera)
- [5. El `shared dict` No Necesita Bloqueos](#5-el-shared-dict-no-necesita-bloqueos)
- [6. Operaciones de Tiempo en OpenResty](#6-operaciones-de-tiempo-en-openresty)
- [Resumen](#resumen)
