O Nginx é um servidor Web que resolve dezenas de tarefas de negócios, é configurado de forma flexível, dimensionado e funciona em quase todos os sistemas operacionais e plataformas. Uma lista de recursos, capacidades e problemas a serem resolvidos imediatamente pode ser descrita em uma pequena brochura. Mas, às vezes, várias tarefas de negócios podem ser resolvidas apenas desenvolvendo seus próprios módulos para o nginx. Esses são módulos orientados aos negócios e contêm alguma lógica comercial, e não apenas uma solução de sistema generalizada.

Em geral, tudo no nginx são módulos que foram escritos por alguém. Portanto, escrever módulos no nginx não é apenas possível, mas também necessário. Quando é necessário fazê-lo e por quê,
Vasily Soshnikov (
dedokOne ) conta o exemplo de vários casos.
Vamos falar sobre os motivos que incentivam a escrita de módulos em C, a arquitetura e o núcleo do nginx, a anatomia dos módulos HTTP, os módulos C, NJS, Lua e nginx.conf. É importante saber não apenas para quem se desenvolve no nginx, mas também para quem usa o nginx-configs, Lua ou outra linguagem dentro do nginx.
Nota: o artigo é baseado em um relatório de Vasily Soshnikov. O relatório está sendo constantemente atualizado e atualizado. As informações no material são bastante técnicas e, para aproveitar ao máximo, os leitores precisam ter experiência trabalhando com o código nginx em um nível médio e acima.Brevemente sobre nginx
Tudo o que você usa com o nginx são os módulos . Cada diretiva na configuração do nginx é um módulo separado, que foi cuidadosamente escrito por colegas da comunidade nginx.
As diretivas no nginx.conf também são módulos que resolvem um problema específico. Portanto, nos módulos nginx são tudo. add_header, proxy_pass, qualquer diretiva - estes são módulos ou combinações de módulos que funcionam de acordo com certas regras.
O Nginx é uma estrutura que possui: E / S de rede e arquivos, memória compartilhada, configuração e script. Essa é uma enorme camada de bibliotecas de baixo nível, nas quais você pode fazer qualquer coisa para trabalhar com as unidades de rede.
O Nginx é rápido e estável, mas complexo . Você deve escrever esse código para não perder essas qualidades do nginx. Nginx instável na produção são clientes insatisfeitos, e tudo o que se segue disso.
Por que criar seus próprios módulos
Converta o protocolo HTTP em outro protocolo. Esse é o principal motivo que muitas vezes motiva a criação de um módulo específico.
Por exemplo, o módulo memcached_pass converte HTTP em outro protocolo e você pode trabalhar com outros sistemas externos. O módulo proxy_pass também permite a conversão, embora de HTTP (s) para HTTP (s). Outro bom exemplo é o fastcgi_pass.
Estas são todas as diretrizes do formulário: "vá para tal e qual back-end, onde não HTTP (mas no caso do proxy_pass HTTP)."
Inserção dinâmica de conteúdo: desvio do AdBlock, inserção de anúncio. Por exemplo, temos um back-end e é necessário modificar o conteúdo que vem dele. Por exemplo, o AdBlock, que analisa o código de inserção de anúncios e precisamos lidar com ele - para ajustá-lo de uma maneira ou de outra.
Outra coisa que você costuma fazer para incorporar conteúdo é o problema com o cache do HLS. Quando os parâmetros são armazenados em cache no HLS, dois usuários podem obter a mesma sessão ou os mesmos parâmetros. A partir daí, você recorta ou adiciona alguns parâmetros quando precisa rastrear alguma coisa.
Coleta de dados de fluxo de cliques dos medidores da Internet / dispositivos móveis. Um caso popular na minha prática. Geralmente, isso é feito no nginx, mas não no access.log, mas um pouco mais inteligente.
Convertendo todos os tipos de conteúdo. Por exemplo, o módulo rtmp para permite trabalhar não apenas com o rtmp, mas também com o HLS. Este módulo pode fazer muito com conteúdo de vídeo.
Ponto de autorização genérico: SEP ou Api Gateway. É o caso quando o nginx funciona como parte da infraestrutura: autoriza, coleta métricas, envia dados para monitoramento e ClickStream. O Nginx funciona aqui como um hub de infraestrutura - um único ponto de entrada para back-end.
Enriquecimento de pedidos para seu rastreio subsequente. Os sistemas modernos são muito complexos, com vários tipos de back-end que formam equipes diferentes. Como regra, eles são difíceis de estrear, às vezes é até difícil entender de onde veio a solicitação e para onde foi. Para simplificar a depuração, algumas grandes empresas usam uma técnica complicada - elas adicionam certos dados às solicitações. O usuário não os verá, mas a partir desses dados é fácil rastrear o caminho da solicitação dentro do sistema. Isso é chamado de
rastreamento .
Proxy S3. Este ano, muitas vezes vejo pessoas trabalhando com seus objetos através do s3. Mas não é necessário fazer isso nos módulos C, a infraestrutura também é suficiente no nginx. Para resolver alguns desses problemas, você pode usar Lua, algo está sendo resolvido no NJS. Mas às vezes é necessário escrever módulos em C.
Quando é a hora de criar módulos
Existem dois critérios para entender que chegou a hora.
Generalização de funcionalidade. Quando você entender que outra pessoa precisa do seu produto, estará contribuindo com o Código Aberto, criando funcionalidades generalizadas, publicando-as e permitindo que sejam usadas.
Resolvendo problemas de negócios. Quando uma empresa define esses requisitos que podem ser satisfeitos apenas escrevendo seu próprio módulo para o nginx. Por exemplo, inserção dinâmica / alteração de conteúdo, a coleção ClickStream pode ser feita em Lua, mas provavelmente não funcionará normalmente.
Arquitetura Nginx
Eu tenho escrito código nginx por um longo tempo. Nove dos meus módulos estão girando em produção, um deles em código aberto e em produção para muitos. Portanto, tenho experiência e entendimento.
Nginx é uma boneca de nidificação, na qual tudo é construído em torno do kernel.
Então eu entendo nginx.
Core são invólucros sobre epoll.
Epoll é um método que permite trabalhar de forma assíncrona com qualquer arquivo descritor, não apenas soquetes, porque um descritor não é apenas um soquete.
Acima do núcleo estão upstreams, HTTP e scripts. Por script, quero dizer nginx.conf, não NJS. Além dos fluxos upstream, HTTP e scripts, os módulos HTTP já foram criados, sobre os quais falaremos.

Um exemplo clássico de upstreams e HTTP são servidores upstream - diretivas dentro da configuração. Um exemplo de módulo para HTTP é add_header. Um exemplo de script é o próprio arquivo de configuração. O arquivo contém os módulos nos quais o nginx consiste; ele é interpretado de alguma forma e permite que você faça algo como administrador ou como usuário.
Não consideraremos o núcleo e nos deteremos muito brevemente nas correntes ascendentes, porque é um universo separado dentro do nginx. A história sobre eles é digna de vários artigos.
Anatomia de módulos HTTP
Mesmo se você não escrever o código C dentro do nginx, mas usá-lo, lembre-se da regra principal.
No nginx, tudo obedece ao padrão da Cadeia de Responsabilidade - COR.
Não sei como traduzir isso para o russo, mas descreverei a lógica. Sua solicitação passa por uma galáxia de módulos de cadeia configurados, a partir do local. Cada um desses módulos retorna um resultado. Se o resultado for ruim, a cadeia é interrompida.

Ao desenvolver módulos ou usar alguma diretiva no NJS e Lua, não esqueça que seu código pode travar a execução dessa cadeia.
A analogia mais próxima da
Cadeia de Responsabilidade é uma linha de código Bash:
grep -RI pool nginx | awk -F":" '{print $1}' | sort -u | wc -l
No código, tudo é bem simples: se o AWK cair no meio da linha, a
sort
e os seguintes comandos não serão executados. O módulo nginx funciona da mesma forma, mas a verdade está no nginx e você pode contornar isso - reinicie o código. Mas você deve estar preparado para travar e executar, assim como seus módulos que você usa na configuração, mas não o fato de que é assim.
Tipos de módulos HTTP
HTTP e nginx são um monte de PHASEs diferentes.
- Manuseio de fases - manipuladores PHASE .
- Filtros - Filtros de corpo / cabeçalhos . Essa filtragem é um cabeçalho ou um corpo de solicitação.
- Proxies . Módulos de proxy típicos são proxy_pass, fastcgi_pass, memcached_pass.
- Módulos para balanceamento de carga específico - Balanceadores de carga . Este é o tipo de módulo mais torcido, eles não estão sendo desenvolvidos muito. Um exemplo é o módulo Ketama CHash, que permite fazer hash consistente dentro do nginx para distribuir solicitações para back-end.
Vou contar sobre cada um desses tipos e seus propósitos.
Manipuladores de fase
Imagine que temos várias fases, começando na fase de acesso. Existem vários módulos em cada fase. Por exemplo, a fase ACCESS é dividida em uma conexão, uma solicitação ao nginx, verificação da autorização do usuário. Cada módulo é uma célula da cadeia. Pode haver um número infinito desses módulos em fase.

O último manipulador final é a fase CONTENT em que o conteúdo é entregue sob demanda.
O caminho é sempre o seguinte: request - uma cadeia de manipuladores - conteúdo de saída.
Fases disponíveis para desenvolvedores de módulos das
fontes 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;
As fases podem ser substituídas, adicione seu próprio manipulador. Nem todos eles são necessários na vida real, se você não é o desenvolvedor do nginx core. Portanto, não falarei sobre cada fase, mas apenas sobre as principais que usei.
O principal é
ACCESS_PHASE. É especialmente útil adicionar sua autorização ao nginx - para verificar a execução da solicitação em termos de acesso.
As próximas fases importantes que frequentemente exploro são as fases de pré-conteúdo e conteúdo.
PRECONTENT_PHASE permite coletar métricas sobre o conteúdo que será enviado como resposta ao cliente.
CONTENT_PHASE permite gerar seu próprio conteúdo exclusivo com base em algo.
A última fase que costumo usar é a fase de log
LOG_PHASE. Aliás, a diretiva ACCESS_LOG funciona nela. A fase de log tem as restrições mais loucas que me deixam louco: você não pode usar sub-requisições e geralmente não pode usar nenhuma solicitação. Você já deixou o conteúdo para o usuário, e manipuladores, manipuladores de postagens e qualquer sub-solicitação não serão executados.
Vou explicar por que é chato. Digamos quando você deseja cruzar nginx e Kafka na fase de criação de log. Nesta fase, tudo já foi concluído: existe um tamanho calculado do conteúdo, status, todos os dados, mas você não pode fazer uma sub-solicitação. Eles não trabalham lá. Você precisa escrever em soquetes nus na fase de registro para enviar dados ao Kafka.
Filtros de corpo / cabeçalhos
Existem dois tipos de filtros: filtros corporais e filtros de cabeçalhos.
Um exemplo de
filtro Body é o módulo de filtro gzip. Por que são necessários filtros corporais? Imagine que você tem um determinado proxy_pass e deseja transformar o conteúdo ou analisá-lo. Nesse caso, você deve usar o filtro Corpo.
Funciona assim: muitos pedaços chegam até você, você faz algo com eles, olha o conteúdo, agrega, etc. Mas o filtro também tem limitações significativas. Por exemplo, se você decidir alterar o corpo - para inserir ou cortar o corpo da resposta, lembre-se de que os atributos HTTP, por exemplo, um feed de conteúdo, serão substituídos. Isso pode levar a efeitos estranhos se você não fornecer restrições e refletir corretamente no seu código.
Um exemplo de
filtro de cabeçalho é o add_header que todos usaram. O algoritmo funciona como no filtro Corpo. Uma resposta é preparada para o cliente, e o filtro add_header permite fazer algo: adicionar cabeçalho, excluir cabeçalho, substituir cabeçalho, enviar sub-solicitação.
A propósito, nas sub-solicitações do filtro Corpo e no filtro Cabeçalho, você pode até enviar identificações internas para um local adicional.
Proxy
Esse é o tipo de módulo mais complexo e controverso que permite proxy de solicitações para sistemas externos, por exemplo,
converter HTTP para outro protocolo . Exemplos: proxy_pass, redis_pass, tnt_pass.
Proxy é uma interface que os desenvolvedores principais do nginx propuseram para facilitar a gravação de módulos proxy. Se isso for feito da maneira clássica, serão executados, para os manipuladores PHASES, filtros, filtros e balanceadores. No entanto, se o protocolo no qual você deseja converter o HTTP for diferente dos clássicos, grandes problemas começarão. A API de proxy fornecida pelo nginx simplesmente não é adequada - você precisa inventar esse módulo de proxy do zero.
Um bom exemplo desse módulo é o postgres_pass. Ele permite que o nginx se comunique com o PostgreSQL. O módulo não usa a interface que foi desenvolvida no nginx - ele possui seu próprio caminho.
Lembre-se de proxy, mas de preferência não escreva. Para escrever proxy, você terá que aprender todo o nginx de cor - é muito longo e difícil.
Balanceadores de carga
A tarefa dos balanceadores de carga é muito simples - trabalhar no modo round robin. Imagine que você tenha uma seção upstream, alguns servidores, especifique pesos e métodos de balanceamento. Este é um balanceador de carga típico.
Este modo nem sempre é adequado. Portanto, o módulo Ketama CHash foi desenvolvido, onde é possível obter condicionalmente uma solicitação de hash consistente para algum servidor. Às vezes é conveniente. O Nginx Lua oferece balancer_by_lua. Em Lua, você pode escrever qualquer balanceador em geral.
Módulos C
A seguir, minha opinião absolutamente subjetiva sobre o desenvolvimento de módulos C. Para começar - minhas regras subjetivas.
O módulo inicia com as diretivas nginx.conf. Mesmo se você estiver criando um módulo C que será operado apenas pela sua empresa, sempre pense nas diretrizes. Comece a projetar o módulo com eles, porque é com isso que o administrador do sistema se comunicará. Isso é importante - coordene todas as nuances com ele ou com a pessoa que irá operar o seu módulo C. NGINX é um produto conhecido, suas diretrizes obedecem a certas leis que os administradores de sistemas conhecem. Portanto, sempre pense sobre isso.
Use o estilo de código nginx. Imagine que seu módulo será suportado por outra pessoa. Se ele já estiver familiarizado com o nginx e seu estilo de código, será muito mais fácil para ele ler e entender seu código.
Recentemente, um bom amigo da Alemanha me pediu para ajudá-lo a lidar com um bug dentro de seu código nginx. Não sei para qual estilo de código ele o escreveu, mas não conseguia ler o código normalmente.
Use o pool de memória correto. Sempre tenha isso em mente, mesmo se você tiver muita experiência com o nginx. Um erro típico de um desenvolvedor iniciante de módulo C para o nginx é obter o pool errado.
Um pouco de histórico: o nginx geralmente usa a ideologia de alocadores fracos. Você pode usar o malloc lá, mas não é recomendado. Ele tem suas próprias lajes, seu próprio alocador de memória, você precisa usá-lo. Assim, cada objeto tem um link para seu pool, e esse pool precisa ser usado. Um erro típico de iniciante é usar uma conexão de pool no filtro de cabeçalho, não uma solicitação de pool. Isso significa que, se tivermos uma conexão keep-alive, o pool inchará até ficar sem memória ou outros efeitos colaterais. Portanto, é importante.
Além disso, esses erros são extremamente difíceis de estrear. Valgrind ("syshniks" entenderá) não funciona com alocação de laje - mostra uma imagem estranha.
Não use E / S de bloqueio. Um erro típico de quem deseja aplicar algo externo mais rápido é usar E / S de bloqueio e soquetes de bloqueio. Você nunca pode fazer isso no nginx - existem muitos processos, mas cada processo usa um thread.
Você pode fazer multi-threading, mas, como regra, isso só piora as coisas. Se você usar E / S de bloqueio em uma arquitetura desse tipo, todos estarão esperando por essa peça de bloqueio.
Vou decifrar o que disse acima.
O módulo começa com as diretivas nginx.conf
Decida em quais matrizes sua diretiva deve estar: Principal, Servidor, HTTP, local, local se.
Tente evitar a localização se - como regra, isso leva a um uso muito estranho da configuração do nginx.
Todas as diretivas no nginx vivem em diferentes contextos e em diferentes escopos. A diretiva add_header pode funcionar no nível HTTP, no nível do local, no nível do local se. Isso geralmente é descrito na documentação.
Entenda em que níveis sua diretiva pode funcionar, onde a diretiva é executada: PHASE Handler, Body / Header filter.
Isso é importante porque no nginx a configuração está congelada. Por convenção, quando você escreve add_header em algum lugar acima, esse valor é suavizado no add_header inferior, que você já possui no local. Assim, você adicionará dois cabeçalhos. Isso se aplica a qualquer diretiva.
Se você especificar alguma porta do host, vice-versa - pool de soquetes. Isso deve ser indicado uma vez.
Em geral, eu proibiria qualquer fusão - você simplesmente não precisa. Portanto, você sempre deve determinar claramente em quais matrizes nginx da configuração sua diretiva ou conjunto de diretivas vive.
Bom exemplo:
location /my_location/ { add_header “My-Header” “my value”; }
Aqui add_header é simplesmente adicionado ao local. O mesmo add_header pode estar em algum lugar acima, e tudo seria simplesmente distorcido. Esse é um comportamento documentado e compreensível.
Pense no que pode dificultar a implementação da diretiva.
Imagine que você está desenvolvendo um filtro corporal. Como eu disse acima, o nginx apenas coloca seu módulo em uma cadeia comum e você não tem garantia de que o módulo gzip não entrou na cadeia na frente do seu filtro Body no momento da compilação. Nesse caso, se alguém ativar o módulo gzip, os dados serão enviados ao seu módulo para o gzip. Isso ameaça que você simplesmente não pode fazer nada com o conteúdo. Você pode refazê-lo novamente, por exemplo, mas isso é uma zombaria do ponto de vista da CPU.
As mesmas regras se aplicam a todos os manipuladores de fase - não há garantia de quem será chamado antes e quem será depois. Portanto, respeite quem será chamado e lembre-se de que algum gzip ou outra coisa pode voar inesperadamente para você.
Estilo de código Nginx
Quando você criou o produto, lembre-se de que alguém o apoiará. Não se esqueça do estilo de código nginx.
Antes de escrever seu módulo nginx, familiarize-se com a fonte:
um e o
segundo .
Se, no futuro, você iniciar o desenvolvimento de módulos nginx, estará bem ciente das fontes nginx. Você os amará porque não
há documentação . Você aprenderá bem a estrutura de diretórios nginx, aprenderá a usar Grep, possivelmente Sed, quando precisar transferir algumas partes do nginx para seus módulos.
Conjunto de memórias
Piscinas devem ser usadas corretamente.
Por exemplo, "r-> conexão-> pool! = R-> pool". Em nenhum caso você pode usar a configuração do conjunto de memórias ao processar solicitações, ela aumentará até que o nginx seja reiniciado.
Entenda a vida útil do objeto. Suponha que a reprodução de solicitação tenha exatamente esse tempo de vida útil do pipeline. Nesta piscina, você pode colocar muitas coisas e abrir espaço. A conexão pode viver teoricamente indefinidamente - é melhor colocar algo realmente importante nela.
Tente não usar alocadores externos, por exemplo, malloc / free . Isso tem um efeito ruim na fragmentação da memória. Se você opera com grandes volumes de dados e usa muito malloc, esse nginx fica muito lento.
Para os fãs do Valgrind, existe um hack que permite depurar nginx-pools usando o Valgrind. Isso é importante se você tiver muito código C no nginx, porque mesmo um desenvolvedor experiente no trabalho com memória pode cometer um erro.
Bloqueio de E / S
Tudo é simples aqui - não use E / S de bloqueio.
Caso contrário, pelo menos haverá problemas com as conexões keep-alive, mas, no máximo, tudo funcionará por um período muito longo.
Conheço o caso quando uma pessoa usou o Quora dentro do nginx no modo de bloqueio (não pergunte o porquê). Isso levou ao fato de que as conexões keep-alive abandonaram suas atividades e atingiram o tempo limite o tempo todo. É melhor não fazer isso - tudo funcionará por muito tempo, de forma ineficiente e você terá que alterar imediatamente um milhão de tempos, porque o nginx iniciará o tempo limite em muitas coisas.
Mas existe uma alternativa aos módulos C - NJS e Lua.
Quando você não precisa desenvolver módulos C
Este ano, tive minha primeira experiência trabalhando no NJS, tive uma impressão subjetiva e até percebi o que estava faltando lá, para que tudo estivesse bem. Eu também gostaria de falar sobre minha experiência trabalhando em Lua sob o nginx e, além disso, compartilhar os problemas que estão presentes em Lua.
Lua / LuaJit Essentials
O Nginx não usa Lua, mas LuaJit. Mas isso não é Lua, porque Lua já avançou duas versões e LuaJit está preso em algum lugar no passado.
O autor praticamente não desenvolve LuaJit - ele geralmente vive em garfos. O fork mais atual é o
LuaJit2 . Isso adiciona situações estranhas no mesmo OpenResty.
Coletor de lixo precisa de atenção . O LuaJit não pode superar esse problema - basta apresentar algumas soluções alternativas. Com uma carga enorme, quando muitos Garbage Collector mantidos vivos ficarem visíveis no cliente com falhas no gráfico e erros 500. Existem várias maneiras de lidar com o Garbage Collector em Lua, não vou focar neles aqui. Há muita informação sobre isso na Internet.
A implementação de cadeias leva a problemas de desempenho . Este é apenas o mal de LuaJit, e em Lua foi reparado. A implementação de strings no LuaJit simplesmente desafia qualquer lógica. As linhas ficam mais lentas da maneira mais selvagem, associada à implementação interna.
Incapacidade de usar muitas bibliotecas prontas . Lua está bloqueando inicialmente, portanto, a maioria das bibliotecas em Lua e LuaJit usa E / S de bloqueio. Devido ao fato de o nginx não estar bloqueando, é impossível usar bibliotecas prontas dentro do nginx que usam qualquer E / S de bloqueio. Isso diminuirá a velocidade do nginx.
As razões para usar LuaJit são idênticas às razões para usar módulos:
- prototipagem de módulos complexos;
- Cálculos HMAC, SHA para autorizações;
- balanceadores ;
- pequenas aplicações: manipuladores de cabeçalho, regras para redirecionamentos;
- variáveis de computação para o nginx.conf.
Onde é melhor não usar LuaJit?
A regra principal: não processe um corpo enorme em Lua - isso não funciona.
Manipuladores de conteúdo em Lua também não funcionam . Tente minimizar a lógica para alguns
if
. Um balanceador simples funcionará, mas uma barra lateral em Lua funcionará muito mal.
A memória compartilhada ou o Garbage Collector virá. Não use a memória compartilhada com o Lua - o Garbage Collector irá rapidamente e com garantia levar todo o cérebro à produção.
Não use corotinas com muitos compostos keep-alive. As corotinas geram ainda mais lixo dentro do LuaJit Garbage Collector, o que é ruim.
Se você já está usando LuaJit, lembre-se:
- sobre monitoramento de memória;
- no monitoramento e otimização do trabalho do Garbage Collector;
- sobre como o Garbage Collector funciona, se você escreveu um aplicativo complicado para o LuaJit, porque precisa adicionar algo novo.
Njs
Quando eu estava na NGINX Conf, eles me convenceram de que seria legal não escrever código em C. Eu pensei que tinha que tentar, e foi isso que obtive.
Autorização Funciona, o código é simples, não afeta a velocidade - tudo está ótimo. Meu pequeno
protótipo com o qual comecei é de 10 linhas de código. Mas essas 10 linhas autorizam com s3.
Variáveis de computação para nginx.conf. Muitas variáveis podem ser calculadas usando NJS. Dentro do nginx, isso é legal. Existe esse recurso em Lua, mas existe um Garbage Collector, portanto não é tão legal.
No entanto, nem tudo é tão bom. Para fazer coisas realmente legais no NJS, ele sente falta de algumas coisas.
Memória compartilhada . Consertei a memória compartilhada, esse é meu próprio garfo, e agora é o suficiente.
Filtros que suportam mais fases . No NJS, há apenas a fase e as variáveis de conteúdo, e o filtro de cabeçalho está muito ausente. Você precisa escrever muletas para adicionar muitos cabeçalhos. Não há filtro de corpo suficiente para lógica complexa ou trabalho com conteúdo.
Informações sobre como monitorar e criar um perfil . Agora eu sei como, mas tive que estudar a fonte. Não há informações ou ferramentas suficientes sobre o perfil adequado. Se estiver, está oculto onde não pode ser encontrado. No mesmo ponto, não há informações suficientes sobre
onde posso usar o NJS e onde não posso?
Módulos C. Eu tinha o desejo de expandir o NJS.
Posfácio
Por que criar seus próprios módulos? Resolver problemas gerais e de negócios.
Quando eu preciso implementar módulos em C? Se não houver outras opções. Por exemplo, uma carga pesada, inserção de conteúdo ou economia básica em hardware. Isso deve ser garantido em C. Na maioria dos casos, Lua ou NJS é adequado. Mas você deve sempre pensar à frente.
E na Lua? Quando você não pode escrever em C. Por exemplo, você não precisa converter o corpo da solicitação com RPS enorme. Seu número de clientes está crescendo; em algum momento você deixará de lidar - pense nisso.
NJS? Quando LuaJit está completamente cheio de seu Garbage Collector e strings. Por exemplo, a autorização gerou muitos objetos Garbage em Lua, mas isso não foi crítico. No entanto, isso se refletiu no monitoramento e irritante. Agora deixou de aparecer no meu monitoramento, e tudo ficou bom.
No HighLoad ++ 2019, Vasily Soshnikov continuará o tópico dos módulos nginx e conversará mais sobre o NJS, sem esquecer a comparação com LuaJit e C.
Veja a lista completa de relatórios no site e nos dias 7 e 8 de novembro na maior conferência para desenvolvedores de sistemas altamente carregados. Siga nossas novas idéias no canal de newsletter e telegrama .