Nginx es un servidor web que resuelve docenas de tareas comerciales, está configurado de forma flexible, escalado y funciona en casi todos los sistemas operativos y plataformas. En un pequeño folleto se puede describir una lista de características, capacidades y problemas que se resolverán de inmediato. Pero a veces, una serie de tareas comerciales se pueden resolver solo desarrollando sus propios módulos para nginx. Estos son módulos que están orientados a los negocios y contienen cierta lógica comercial, y no solo una solución de sistema generalizada.

En general, todo en nginx son módulos que alguna vez fueron escritos por alguien. Por lo tanto, escribir módulos bajo nginx no solo es posible, sino también necesario. Cuando sea necesario hacerlo y por qué,
Vasily Soshnikov (
dedokOne ) contará el ejemplo de varios casos.
Hablemos de las razones que fomentan la escritura de módulos en C, la arquitectura y el núcleo de nginx, la anatomía de los módulos HTTP, los módulos C, NJS, Lua y nginx.conf. Es importante saberlo no solo para aquellos que se desarrollan bajo nginx, sino también para aquellos que usan nginx-configs, Lua u otro lenguaje dentro de nginx.
Nota: el artículo se basa en un informe de Vasily Soshnikov. El informe se actualiza y actualiza constantemente. La información en el material es bastante técnica y para aprovecharla al máximo, los lectores deben tener experiencia trabajando con código nginx a un nivel promedio y superior.Brevemente sobre nginx
Todo lo que usa con nginx son módulos . Cada directiva en la configuración de nginx es un módulo separado, que fue cuidadosamente escrito por colegas de la comunidad nginx.
Las directivas en nginx.conf también son módulos que resuelven un problema específico. Por lo tanto, en nginx los módulos lo son todo. add_header, proxy_pass, cualquier directiva: son módulos o combinaciones de módulos que funcionan de acuerdo con ciertas reglas.
Nginx es un marco que tiene: red y E / S de archivos, memoria compartida, configuración y secuencias de comandos. Esta es una gran capa de bibliotecas de bajo nivel, en la que puede hacer cualquier cosa para trabajar con las unidades de red.
Nginx es rápido y estable, pero complejo . Debería escribir dicho código para no perder estas cualidades de nginx. Los nginx inestables en producción son clientes insatisfechos, y todo lo que sigue de esto.
¿Por qué crear sus propios módulos?
Convierta el protocolo HTTP a otro protocolo. Esta es la razón principal que a menudo motiva la creación de un módulo en particular.
Por ejemplo, el módulo memcached_pass convierte HTTP a otro protocolo y puede trabajar con otros sistemas externos. El módulo proxy_pass también le permite convertir, aunque de HTTP (s) a HTTP (s). Otro buen ejemplo es fastcgi_pass.
Estas son todas las directivas de la forma: "vaya a tal y tal backend, donde no HTTP (sino en el caso de proxy_pass HTTP)".
Inserción de contenido dinámico: omisión de AdBlock, inserción de anuncios. Por ejemplo, tenemos un back-end y es necesario modificar el contenido que proviene de él. Por ejemplo, AdBlock, que analiza el código de inserción de anuncios, y tenemos que lidiar con él para ajustarlo de una forma u otra.
Otra cosa que a menudo tiene que hacer para incrustar contenido es el problema con el almacenamiento en caché de HLS. Cuando los parámetros se almacenan en caché dentro de HLS, entonces dos usuarios pueden obtener la misma sesión o los mismos parámetros. A partir de ahí, corta o agrega algunos parámetros cuando necesita rastrear algo.
Recopilación de datos de Clickstream desde internet / medidores móviles. Un caso popular en mi práctica. La mayoría de las veces esto se hace en nginx, pero no en access.log, pero un poco más inteligente.
Convirtiendo todo tipo de contenido. Por ejemplo, el módulo rtmp le permite trabajar no solo con rtmp, sino también con HLS. Este módulo puede hacer mucho con contenido de video.
Punto de autorización genérico: SEP o Api Gateway. Este es el caso cuando nginx funciona como parte de la infraestructura: autoriza, recopila métricas, envía datos a monitoreo y ClickStream. Nginx funciona aquí como un centro de infraestructura: un único punto de entrada para backends.
Enriquecimiento de las solicitudes para su posterior seguimiento. Los sistemas modernos son muy complejos, con varios tipos de backends que forman diferentes equipos. Como regla, son difíciles de debutar, a veces incluso es difícil entender de dónde vino la solicitud y hacia dónde se fue. Para simplificar la depuración, algunas grandes empresas utilizan una técnica complicada: agregan ciertos datos a las solicitudes. El usuario no los verá, pero a partir de estos datos es fácil rastrear la ruta de solicitud dentro del sistema. Esto se llama
rastro .
S3-proxy. Este año, a menudo veo personas trabajando con sus objetos a través de s3. Pero no es necesario hacer esto en los módulos C, la infraestructura también es suficiente en nginx. Para resolver algunos de estos problemas, puede usar Lua, algo se está resolviendo en NJS. Pero a veces es necesario escribir módulos en C.
¿Cuándo es el momento de crear módulos?
Hay dos criterios para entender que ha llegado el momento.
Generalización de la funcionalidad. Cuando comprende que alguien más necesita su producto, está contribuyendo a Open Source, creando una funcionalidad generalizada, publicándola y permitiendo que se use.
Resolviendo problemas de negocios. Cuando una empresa establece requisitos que solo se pueden cumplir escribiendo su propio módulo para nginx. Por ejemplo, la inserción / cambio dinámico de contenido, la colección ClickStream se puede hacer en Lua, pero lo más probable es que no funcione normalmente.
Arquitectura Nginx
He estado escribiendo código nginx durante mucho tiempo. Nueve de mis módulos están girando en producción, uno de ellos está en código abierto y en producción para muchos. Por lo tanto, tengo experiencia y comprensión.
Nginx es una muñeca de anidación en la que todo está construido alrededor del núcleo.
Entonces entiendo nginx.
Los núcleos son envoltorios sobre epoll.
Epoll es un método que le permite trabajar de forma asíncrona con cualquier archivo descriptor, no solo con sockets, porque un descriptor no es solo un socket.
Por encima del núcleo están las cadenas ascendentes, HTTP y secuencias de comandos. Por scripts, me refiero a nginx.conf, no a NJS. Además de upstreams, HTTP y scripting, los módulos HTTP ya están construidos, de lo que hablaremos.

Un ejemplo clásico de upstreams y HTTP son servidores upstream: directivas dentro de la configuración. Un ejemplo de módulos para HTTP es add_header. Un ejemplo de scripting es el archivo de configuración en sí. El archivo contiene los módulos en los que consta nginx; se interpreta de alguna manera y le permite hacer algo como administrador o como usuario.
No consideraremos el núcleo y nos detendremos brevemente en las aguas arriba, porque es un universo separado dentro de nginx. La historia sobre ellos es digna de varios artículos.
Anatomía de los módulos HTTP
Incluso si no escribe código C dentro de nginx, pero lo usa, recuerde la regla principal.
En nginx, todo obedece al patrón de la Cadena de Responsabilidad - COR.
No sé cómo traducir esto al ruso, pero describiré la lógica. Su solicitud pasa por una galaxia de módulos de cadena configurados, comenzando desde la ubicación. Cada uno de estos módulos devuelve un resultado. Si el resultado es malo, la cadena se interrumpe.

Cuando desarrolle módulos o use alguna directiva en NJS y Lua, no olvide que su código puede bloquear la ejecución de esta cadena.
La analogía más cercana a la
Cadena de responsabilidad es una línea de código Bash:
grep -RI pool nginx | awk -F":" '{print $1}' | sort -u | wc -l
En el código, todo es bastante simple: si AWK cayó en el medio de la línea, entonces
sort
y los siguientes comandos fallarán. El módulo nginx funciona de manera similar, pero la verdad está en nginx y puede solucionarlo: reinicie el código. Pero debe estar preparado para bloquearse y ejecutarse, al igual que los módulos que usa en la configuración, pero no el hecho de que esto sea así.
Tipos de módulos HTTP
HTTP y nginx son un montón de PHASE diferentes.
- Manejo de fase: manejadores de FASE .
- Filtros: filtros de cuerpo / encabezados . Este filtrado es encabezados o cuerpos de solicitud.
- Proxies . Los módulos proxy típicos son proxy_pass, fastcgi_pass, memcached_pass.
- Módulos para balanceo de carga específico - Balanceadores de carga . Este es el tipo de módulos más retorcido, no se están desarrollando mucho. Un ejemplo es el módulo Ketama CHash, que le permite realizar hashing coherente dentro de nginx para distribuir solicitudes a backends.
Le contaré sobre cada uno de estos tipos y su propósito.
Manejadores de fase
Imagine que tenemos varias fases, comenzando desde la fase de acceso. Hay varios módulos en cada fase. Por ejemplo, la fase ACCESS se divide en una conexión, una solicitud a nginx, verificación de la autorización del usuario. Cada módulo es una celda en la cadena. Puede haber un número infinito de tales módulos en fase.

El último controlador final es la fase de CONTENIDO en la que el contenido se entrega a pedido.
La forma es siempre esta: solicitud - una cadena de controladores - contenido de salida.
Fases disponibles para los desarrolladores de módulos de las
fuentes NGINX :
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_ACESS_PHASE, NGX_HTTP_POST_ACESS_PHASE, NGX_HTTP_PRECONTENT_PHASE, NGX_HTTP_CONTENT_PHASE, NGX_HTTP_LOG_PHASE, } ngx_http_phases;
Las fases se pueden sobrescribir, agregue su propio controlador. No todos son necesarios en la vida real, si no eres el desarrollador de nginx core. Por lo tanto, no hablaré sobre cada fase, sino solo sobre las principales que usé.
El principal es
ACCESS_PHASE. Es especialmente útil agregar su autorización a nginx, para verificar la ejecución de la solicitud en términos de acceso.
Las siguientes fases importantes que a menudo exploto son las fases de contenido previo y contenido.
PRECONTENT_PHASE le permite recopilar métricas sobre el contenido que está a punto de enviarse como respuesta al cliente.
CONTENT_PHASE te permite generar tu propio contenido único basado en algo.
La última fase que uso a menudo es la fase de registro
LOG_PHASE. Por cierto, la directiva ACCESS_LOG funciona en ella. La fase de inicio de sesión tiene las restricciones más salvajes que me vuelven loco: no puede usar subrequest y generalmente no puede usar ninguna solicitud. Ya ha dejado el contenido al usuario, y no se ejecutarán los manejadores, los manejadores posteriores ni ninguna subrequest.
Explicaré por qué es molesto. Digamos cuando quiere cruzar nginx y Kafka en la fase de registro. En esta fase, todo ya se ha completado: hay un tamaño calculado del contenido, el estado, todos los datos, pero no puede hacerlo a continuación. No trabajan allí. Debe escribir en sockets desnudos en la fase de registro para enviar datos a Kafka.
Filtros de cuerpo / encabezados
Hay dos tipos de filtros: filtros de cuerpo y filtros de encabezados.
Un ejemplo de
filtro Body es el módulo de filtro gzip. ¿Por qué se necesitan filtros corporales? Imagine que tiene un cierto proxy_pass y desea de alguna manera transformar el contenido o analizarlo. En este caso, debe usar el filtro Cuerpo.
Funciona así: muchos trozos vienen a ti, haces algo con ellos, miras el contenido, el agregado, etc. Pero el filtro también tiene limitaciones significativas. Por ejemplo, si decide cambiar el cuerpo, para insertar o recortar el cuerpo de la respuesta, recuerde que los atributos HTTP, por ejemplo, una fuente de contenido, serán reemplazados. Esto puede provocar efectos extraños si no establece restricciones y se refleja correctamente en su código.
Un ejemplo de un
filtro de encabezado es el add_header que todos han usado. El algoritmo funciona como en el filtro Body. Se prepara una respuesta para el cliente, y el filtro add_header le permite hacer algo allí: agregar encabezado, eliminar encabezado, reemplazar encabezado, enviar subrequest.
Por cierto, en el filtro Cuerpo y en el filtro de Encabezado están disponibles las subrequests, incluso puedes enviar identificaciones internas a una ubicación adicional allí.
Proxy
Este es el tipo de módulos más complejo y controvertido que le permite enviar solicitudes de proxy a sistemas externos, por ejemplo,
convertir HTTP a otro protocolo . Ejemplos: proxy_pass, redis_pass, tnt_pass.
Proxy es una interfaz que los desarrolladores principales de nginx han propuesto para facilitar la escritura de módulos proxy. Si esto se hace de la manera clásica, entonces para dichos controladores proxy PHASES, filtros, se ejecutarán Balanceadores. Sin embargo, si el protocolo al que desea convertir HTTP es de alguna manera diferente de los clásicos, entonces comienzan los grandes problemas. La API proxy que ofrece nginx simplemente no es adecuada: debe inventar este módulo proxy desde cero.
Un buen ejemplo de dicho módulo es postgres_pass. Permite que nginx se comunique con PostgreSQL. El módulo no utiliza la interfaz que se desarrolló en nginx, tiene su propia ruta.
Recuerde proxy, pero preferiblemente no escriba. Para escribir proxy, tendrá que aprender todos los nginx de memoria: es muy largo y difícil.
Equilibradores de carga
La tarea de los equilibradores de carga es muy simple: trabajar en modo round-robin. Imagine que tiene una sección ascendente, algunos servidores en ella, especifica pesos y métodos de equilibrio. Este es un equilibrador de carga típico.
Este modo no siempre es adecuado. Por lo tanto, se desarrolló el módulo Ketama CHash, donde es condicionalmente posible llegar a una solicitud de hash consistente para algún servidor. A veces es conveniente. Nginx Lua ofrece balancer_by_lua. En Lua, puede escribir cualquier equilibrador en general.
Módulos C
Lo siguiente será mi opinión absolutamente subjetiva sobre el desarrollo de módulos C. Para empezar, mis reglas subjetivas.
El módulo comienza con las directivas nginx.conf. Incluso si está creando un módulo C que solo será operado por su empresa, siempre piense en las directivas. Comience a diseñar el módulo con ellos, porque esto es con lo que se comunicará el administrador del sistema. Esto es importante: coordine todos los matices con él o con la persona que operará su módulo C. NGINX es un producto bien conocido, sus directivas obedecen ciertas leyes que los administradores de sistemas conocen. Por lo tanto, siempre piense en ello.
Usa el estilo de código nginx. Imagine que su módulo será apoyado por otra persona. Si ya está familiarizado con nginx y su estilo de código, será mucho más fácil para él leer y comprender su código.
Recientemente, un buen amigo de Alemania me pidió que lo ayudara a lidiar con un error dentro de su código nginx. No sé para qué estilo de código lo escribió, pero ni siquiera podía leer el código normalmente.
Use el conjunto de memoria correcto. Siempre tenga esto en cuenta, incluso si tiene mucha experiencia con nginx. Un error típico de un desarrollador novato de módulos C para nginx es obtener el grupo incorrecto.
Un poco de historia: nginx generalmente usa la ideología de asignadores débiles. Puede usar malloc allí, pero no se recomienda. Tiene sus propias losas, su propio asignador de memoria, debe usarlo. En consecuencia, cada objeto tiene un enlace a su grupo, y este grupo debe ser utilizado. Un error típico de un novato es usar una conexión de grupo en el filtro de encabezado, no una solicitud de grupo. Esto significa que si tenemos una conexión para mantener vivo, el grupo se hinchará hasta que se quede sin memoria u otros efectos secundarios. Por eso es importante.
Además, tales errores son extremadamente difíciles de debutar. Valgrind ("syshniks" lo entenderá) no funciona con la asignación de losas, mostrará una imagen extraña.
No utilice el bloqueo de E / S. Un error típico de aquellos que desean aplicar algo externo más rápido es usar E / S de bloqueo y enchufes de bloqueo. Nunca puede hacer esto en nginx: hay muchos procesos en él, pero cada proceso usa un hilo.
Puede hacer subprocesos múltiples, pero, por regla general, esto solo lo empeora. Si utiliza E / S de bloqueo en una arquitectura de este tipo, todos estarán esperando esta pieza de bloqueo.
Descifraré lo que dije anteriormente.
El módulo comienza con las directivas nginx.conf
Decida en qué matrices debe vivir su directiva: Principal, Servidor, HTTP, ubicación, ubicación si.
Intente evitar la ubicación si, como regla, esto lleva a un uso muy extraño de la configuración de nginx.
Todas las directivas en nginx viven en diferentes contextos y en diferentes ámbitos. La directiva add_header puede funcionar en el nivel HTTP, en el nivel de ubicación, en el nivel de ubicación si. Esto generalmente se describe en la documentación.
Comprenda en qué niveles puede funcionar su directiva, dónde se ejecuta la directiva: PHASE Handler, Body / Header filter.
Esto es importante porque en nginx la configuración está congelada. Por convención, cuando escribe add_header en algún lugar arriba, este valor se suaviza en el add_header inferior, que ya tiene en la ubicación. En consecuencia, agregará dos encabezados. Esto se aplica a cualquier directiva.
Si especifica algo de puerto de host, entonces viceversa - grupo de sockets. Esto debe indicarse una vez.
En general, prohibiría cualquier fusión, simplemente no la necesita. Por lo tanto, siempre debe determinar claramente en qué matrices nginx de la configuración vive su directiva o conjunto de directivas.
Buen ejemplo:
location /my_location/ { add_header “My-Header” “my value”; }
Aquí add_header simplemente se agrega a la ubicación. El mismo add_header podría estar en algún lugar arriba, y todo simplemente estaría contorsionado. Este es un comportamiento documentado y comprensible.
Piense en lo que podría dificultar la implementación de la directiva.
Imagina que estás desarrollando un filtro Body. Como dije anteriormente, nginx simplemente coloca su módulo en una cadena común, y no tiene garantía de que el módulo gzip no haya entrado en la cadena frente a su filtro Body en el momento de la compilación. En este caso, si alguien enciende el módulo gzip, los datos se enviarán a su módulo para el gzip. Esto amenaza con que simplemente no puede hacer nada con el contenido. Puede volver a comprimirlo, por ejemplo, pero esto es una burla desde el punto de vista de la CPU.
Las mismas reglas se aplican a todos los manejadores de fase: no hay garantía de quién será llamado antes y quién será después. Por lo tanto, respeta al que será llamado después y recuerda que algún gzip u otra cosa puede volar inesperadamente hacia ti.
Estilo de código Nginx
Cuando creaste el producto, recuerda que alguien lo apoyará. No te olvides del estilo de código nginx.
Antes de escribir su módulo nginx, familiarícese con la fuente:
una y la
segunda .
Si en el futuro emprende el desarrollo de módulos nginx, entonces estará al tanto de las fuentes nginx. Los amarás porque no
hay documentación . Aprenderá bien la estructura de directorios de nginx, aprenderá a usar Grep, posiblemente Sed, cuando necesite transferir algunas piezas de nginx a sus módulos.
Grupo de memoria
Las piscinas deben usarse correctamente.
Por ejemplo, "r-> conexión-> pool! = R-> pool". En ningún caso puede usar la configuración de agrupación de memoria al procesar solicitudes, se hinchará hasta que se reinicie nginx.
Comprender la vida útil del objeto. Supongamos que la repetición de solicitudes tiene exactamente esta vida útil de canalización. En esta piscina puedes colocar muchas cosas y hacer espacio. La conexión puede vivir teóricamente indefinidamente: es mejor colocar algo realmente importante en ella.
Intente no utilizar asignadores externos, por ejemplo, malloc / free . Esto tiene un efecto negativo en la fragmentación de la memoria. Si opera con grandes volúmenes de datos y usa una gran cantidad de malloc, este nginx se ralentiza bastante bien.
Para los fanáticos de Valgrind, existe un truco que les permite depurar nginx-pools usando Valgrind. Esto es importante si tiene mucho código C en nginx, porque incluso un desarrollador experimentado en trabajar con memoria puede cometer un error.
Bloqueo de E / S
Aquí todo es simple: no use el bloqueo de E / S.
De lo contrario, al menos habrá problemas con las conexiones de mantenimiento, pero como máximo, todo funcionará durante mucho tiempo.
Sé el caso cuando una persona usó Quora dentro de nginx en modo de bloqueo (no pregunte por qué). Esto llevó al hecho de que las conexiones para mantener vivo abandonaron su actividad y expiraron todo el tiempo. Es mejor no hacer esto: todo funcionará durante mucho tiempo, de manera ineficiente e inmediatamente tendrá que cambiar un millón de tiempos de espera, porque nginx comenzará el tiempo de espera en muchas cosas.
Pero hay una alternativa a los módulos C: NJS y Lua.
Cuando no necesita desarrollar módulos C
Este año tuve mi primera experiencia trabajando en NJS, tuve una impresión subjetiva e incluso me di cuenta de lo que faltaba allí, de modo que todo estaba bien. También me gustaría hablar sobre mi experiencia trabajando en Lua con nginx y, además, compartir los problemas que están presentes en Lua.
Lua / LuaJit Essentials
Nginx no usa Lua, sino LuaJit. Pero esto no es Lua, porque Lua ya ha avanzado dos versiones, y LuaJit está atrapado en algún lugar del pasado.
El autor prácticamente no desarrolla LuaJit, a menudo vive en tenedores. La bifurcación más actual es
LuaJit2 . Esto agrega situaciones extrañas en el mismo OpenResty.
El recolector de basura necesita atención . LuaJit no puede superar este problema, solo encuentre algunas soluciones. Con una carga enorme, cuando una gran cantidad de Garbage Collector se mantendrá vivo en el cliente con fallas en el gráfico y errores 500. Hay muchas maneras de lidiar con Garbage Collector en Lua, no me enfocaré en ellos aquí. Hay mucha información sobre esto en Internet.
La implementación de cadenas conduce a problemas de rendimiento . Esto es solo el mal de LuaJit, y en Lua fue reparado. La implementación de cadenas en LuaJit simplemente desafía cualquier lógica. Las líneas se ralentizan de la manera más salvaje, lo que está asociado con la implementación interna.
Incapacidad para usar muchas bibliotecas preparadas . Lua está inicialmente bloqueando, por lo que la mayoría de las bibliotecas en Lua y LuaJit usan E / S de bloqueo. Debido al hecho de que nginx no está bloqueando, es imposible usar bibliotecas listas para usar dentro de nginx que usen alguna E / S de bloqueo. Esto ralentizará nginx.
Las razones para usar LuaJit son idénticas a las razones para usar módulos:
- creación de prototipos de módulos complejos;
- HMAC, SHA cálculos para autorizaciones;
- equilibradores
- pequeñas aplicaciones: controladores de encabezado, reglas para redireccionamientos;
- variables informáticas para nginx.conf.
¿Dónde es mejor no usar LuaJit?
La regla principal: no procese un gran cuerpo en Lua, esto no funciona.
Los manejadores de contenido en Lua tampoco funcionan . Intenta minimizar la lógica a unos pocos
if
. Un simple equilibrador funcionará, pero una barra lateral en Lua funcionará muy mal.
La memoria compartida o el recolector de basura vendrá. No use la memoria compartida con Lua: Garbage Collector rápidamente y con garantía sacará todo el cerebro a producción.
No use corutinas con muchos compuestos para mantener vivo. Las rutinas generan aún más basura dentro del recolector de basura LuaJit, lo cual es malo.
Si ya está utilizando LuaJit, recuerde:
- sobre monitoreo de memoria;
- en monitorear y optimizar el trabajo de Garbage Collector;
- sobre cómo funciona Garbage Collector, si escribiste una aplicación complicada para LuaJit, porque tienes que agregar algo nuevo.
Njs
Cuando estaba en NGINX Conf, me convencieron de que sería genial no escribir código en C. Pensé que tenía que intentarlo, y eso es lo que obtuve.
Autorización Funciona, el código es simple, no afecta la velocidad, todo es genial. Mi pequeño
prototipo con el que comencé es 10 líneas de código. Pero estas 10 líneas hacen autorización con s3.
Variables de cálculo para nginx.conf. Muchas variables se pueden calcular usando NJS. Dentro de nginx, esto es genial. Hay una función de este tipo en Lua, pero hay un recolector de basura, por lo que no es tan genial.
Sin embargo, no todo es tan bueno. Para hacer cosas realmente geniales en NJS, echa de menos algunas cosas.
Memoria compartida Parcheé la memoria compartida, esta es mi propia bifurcación, así que ahora es suficiente.
Filtros que admiten más fases . En NJS, solo existe la fase de contenido y las variables, y el filtro de encabezado es muy deficiente. Tienes que escribir muletas para agregar muchos encabezados. No hay suficiente filtro corporal para lógica compleja o trabajo con contenido.
Información sobre cómo monitorearlo y perfilarlo . Ahora sé cómo, pero tuve que estudiar la fuente. No hay suficiente información o herramientas sobre el perfil adecuado. Si es así, está oculto donde no se puede encontrar. En el mismo punto, ¿no hay suficiente información sobre
dónde puedo usar NJS y dónde no?
C-módulos . Tenía el deseo de expandir NJS.
Epílogo
¿Por qué crear sus propios módulos? Para resolver problemas generales y empresariales.
¿Cuándo necesito implementar módulos en C? Si no hay otras opciones. Por ejemplo, una carga pesada, inserción de contenido o ahorros básicos en hardware. Entonces esto debe hacerse garantizado en C. En la mayoría de los casos, Lua o NJS es adecuado. Pero siempre debes pensar en el futuro.
¿Y en Lua? Cuando no puede escribir en C. Por ejemplo, no necesita convertir el cuerpo de la solicitud con un gran RPS. Su número de clientes está creciendo, en algún momento dejará de hacer frente, piénselo.
NJS? Cuando LuaJit está completamente harto de su recolector de basura y cadenas. Por ejemplo, la autorización generó muchos objetos basura en Lua, pero esto no fue crítico. Sin embargo, esto se reflejó en el seguimiento y la molestia. Ahora ha dejado de aparecer en mi monitoreo, y todo se ha vuelto bueno.
En HighLoad ++ 2019, Vasily Soshnikov continuará con el tema de los módulos nginx y hablará más sobre NJS, sin olvidar la comparación con LuaJit y C.
Vea la lista completa de informes en el sitio web, y nos vemos el 7 y 8 de noviembre en la conferencia más grande para desarrolladores de sistemas altamente cargados. Siga nuestras nuevas ideas en el boletín y el canal de telegramas .