{"id":71378,"date":"2020-02-25T20:45:02","date_gmt":"2020-02-25T17:45:02","guid":{"rendered":"https:\/\/prohoster.info\/blog\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij"},"modified":"2020-03-03T16:14:21","modified_gmt":"2020-03-03T13:14:21","slug":"openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij","title":{"rendered":"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/62eb484051c7963c96842393884ddd98.jpg\" style=\"display:block;margin: 0 auto;\" \/><em>Estamos publicando novamente a transcri\u00e7\u00e3o da palestra da confer\u00eancia <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/\">HighLoad++<\/a><\/noindex> 2016, que ocorreu em Skolkovo, na regi\u00e3o de Moscou, nos dias 7 e 8 de novembro do ano passado. <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/post\/315726\/\">Vladimir Protassov<\/a><\/noindex> fala sobre como expandir a funcionalidade do NGINX com OpenResty e Lua.<\/em><\/p>\n<p>Ol\u00e1 a todos, meu nome \u00e9 Vladimir Protassov, trabalho na Parallels. Vou contar um pouco sobre mim. Tr\u00eas quartos da minha vida eu escrevo c\u00f3digo. Tornei-me programador at\u00e9 o osso \u2014 em sentido literal: \u00e0s vezes sonho com c\u00f3digo. Um quarto da vida \u00e9 desenvolvimento industrial, escrevendo c\u00f3digo que vai direto para produ\u00e7\u00e3o. O c\u00f3digo que alguns de voc\u00eas usam, mas n\u00e3o t\u00eam ideia disso.<\/p>\n<p>Para voc\u00eas entenderem o quanto a situa\u00e7\u00e3o era cr\u00edtica. Quando eu era um junior, cheguei e me deram bancos de dados de dois terabytes. Agora todos aqui t\u00eam alta carga. Eu ia a confer\u00eancias, perguntava: \"Galera, conta pra mim, voc\u00eas t\u00eam big data, tudo \u00e9 incr\u00edvel? Quantos dados voc\u00eas t\u00eam?\" Eles respondiam: \"Temos 100 gigabytes!\" Eu dizia: \"Incr\u00edvel, 100 gigabytes!\" E pensava: como manter uma express\u00e3o neutra. Voc\u00ea pensa: sim, eles s\u00e3o legais, mas depois retorna e se depara com esses bancos de dados de m\u00faltiplos terabytes. E isso sendo um junior. Consegue imaginar o impacto?<\/p>\n<p>Eu conhe\u00e7o mais de 20 linguagens de programa\u00e7\u00e3o. Essa \u00e9 a base que tive que entender no trabalho. Eles lhe d\u00e3o c\u00f3digo em Erlang, C, C++, Lua, Python, Ruby, e voc\u00ea precisa trabalhar com tudo isso. No geral, foi necess\u00e1rio. N\u00e3o consegui contar exatamente, mas perdi a conta em cerca de 20.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nComo todos aqui presentes sabem o que \u00e9 a Parallels e o que fazemos, n\u00e3o vou falar sobre como somos incr\u00edveis ou o que fazemos. Apenas mencionarei que temos 13 escrit\u00f3rios no mundo, mais de 300 funcion\u00e1rios, com desenvolvimento em Moscovo, Tallinn e Malta. Se algu\u00e9m quiser, pode se mudar para Malta, se estiver frio no inverno e quiser aquecer as costas.<\/p>\n<p>Nosso departamento escreve em Python 2. Estamos focados nos neg\u00f3cios e n\u00e3o temos tempo para implementar as tecnologias da moda, ent\u00e3o estamos lidando com isso. Temos Django, porque nele est\u00e1 tudo o que precisamos, e o que \u00e9 excessivo, jogamos fora. Tamb\u00e9m MySQL, Redis e NGINX. Al\u00e9m disso, temos v\u00e1rias outras coisas legais. Temos MongoDB, temos coelhinhos correndo, temos de tudo \u2014 mas isso n\u00e3o \u00e9 a minha \u00e1rea e eu n\u00e3o cuido disso.<\/p>\n<h1>OpenResty<\/h1>\n<p>\nFalei sobre mim. Vamos entender sobre o que eu vou falar hoje:<\/p>\n<ul>\n<li>O que \u00e9 OpenResty e para que serve?<\/li>\n<li>Por que inventar mais uma bicicleta se j\u00e1 temos Python, NodeJS, PHP, Go e outras coisas legais que todos est\u00e3o satisfeitos?<\/li>\n<li>E alguns exemplos da vida real. Eu tive que cortar bastante a apresenta\u00e7\u00e3o, pois ela estava com 3,5 horas, ent\u00e3o haver\u00e1 poucos exemplos.<\/li>\n<\/ul>\n<p>\nOpenResty \u00e9 NGINX. Gra\u00e7as a ele, temos um servidor web completo, bem escrito e r\u00e1pido. Eu acho que a maioria de n\u00f3s usa NGINX em produ\u00e7\u00e3o. Todos voc\u00eas sabem que ele \u00e9 r\u00e1pido e excelente. Ele possui um \u00f3timo I\/O ass\u00edncrono, ent\u00e3o n\u00e3o precisamos reinventar a roda como fizemos com gevent em Python. Gevent \u00e9 incr\u00edvel, mas se voc\u00ea escrever um c\u00f3digo em C e algo der errado, ser\u00e1 uma loucura debugar com gevent. Eu tive essa experi\u00eancia: levei dois dias para descobrir o que havia ocorrido. Se algu\u00e9m n\u00e3o tivesse investigado isso semanas antes, n\u00e3o tivesse encontrado o problema, n\u00e3o tivesse publicado na internet, e o Google n\u00e3o tivesse achado isso, ter\u00edamos enlouquecido.<\/p>\n<p>O NGINX j\u00e1 possui caching e conte\u00fado est\u00e1tico. Voc\u00ea n\u00e3o precisa se preocupar sobre como fazer isso corretamente, evitando lentid\u00f5es ou perdendo descritores. O NGINX \u00e9 muito f\u00e1cil de implantar, voc\u00ea n\u00e3o precisa se preocupar se deve usar WSGI, PHP-FPM, Gunicorn ou Unicorn. Voc\u00ea instala o NGINX, entrega para os administradores e eles sabem como lidar com isso. O NGINX processa solicita\u00e7\u00f5es de forma estruturada. Eu falarei um pouco mais sobre isso depois. Resumidamente, ele tem uma fase em que recebe a solicita\u00e7\u00e3o, outra em que a processa, e quando entrega o conte\u00fado ao usu\u00e1rio.<\/p>\n<p>O NGINX \u00e9 \u00f3timo, mas h\u00e1 um problema: ele n\u00e3o \u00e9 flex\u00edvel o suficiente, mesmo com todos os recursos incr\u00edveis que a equipe incorporou na configura\u00e7\u00e3o. Essa pot\u00eancia \u00e9 insuficiente. Por isso, os desenvolvedores do Taobao, h\u00e1 cerca de oito anos, integraram o Lua. O que isso proporciona?<\/p>\n<ul>\n<li><strong>Tamanho<\/strong>. Ele \u00e9 pequeno. LuaJIT oferece cerca de 100-200 kilobytes de overhead em mem\u00f3ria e um overhead m\u00ednimo em desempenho.<\/li>\n<li><strong>Velocidade<\/strong>. O interpretador LuaJIT \u00e9, em muitas situa\u00e7\u00f5es, pr\u00f3ximo do C, em algumas ele perde para o Java e em outras o supera. Por um tempo, foi considerado o state of art, o melhor JIT compiler. Atualmente, existem vers\u00f5es melhores, mas s\u00e3o muito pesadas, como o pr\u00f3prio V8. Alguns interpretadores de JS e o HotSpot do Java s\u00e3o mais r\u00e1pidos em certos pontos, mas ainda perdem em outros.<\/li>\n<li><strong>Facilidade de aprendizado<\/strong>. Se voc\u00ea tem uma base de c\u00f3digo em Perl e n\u00e3o \u00e9 a Booking, voc\u00ea n\u00e3o encontrar\u00e1 programadores de Perl. Porque eles n\u00e3o existem, todos foram levados, e ensin\u00e1-los \u00e9 demorado e complicado. Se voc\u00ea precisar de programadores em outra linguagem, talvez tenha que reeduc\u00e1-los ou encontr\u00e1-los. No caso do Lua, \u00e9 simples. Qualquer um aprende Lua em tr\u00eas dias. Eu levei cerca de duas horas para entender. Depois de duas horas, j\u00e1 estava escrevendo c\u00f3digo em produ\u00e7\u00e3o. Mais ou menos uma semana depois, ele j\u00e1 foi para produ\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>\nO resultado fica assim:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/1e6c253c5436fdc894f8be7999799cb0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAqui tem muita coisa. No OpenResty, foram reunidos v\u00e1rios m\u00f3dulos, tanto de Lua quanto da engine. E voc\u00ea tem tudo pronto - implantou e funcionou.<\/p>\n<h1>Exemplos<\/h1>\n<p>\nChega de poesia, vamos ao c\u00f3digo. Aqui est\u00e1 um pequeno Hello World:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/bbd056b72c71b193b0f06dd3248f5381.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nO que temos aqui? \u00e9 um location da engine. N\u00f3s n\u00e3o nos preocupamos, n\u00e3o escrevemos nosso pr\u00f3prio roteamento, nem pegamos algum pronto - j\u00e1 temos no NGINX, estamos vivendo bem e de maneira pregui\u00e7osa.<\/p>\n<p><code>content_by_lua_block<\/code> \u2013 \u00e9 um bloco que diz que estamos entregando conte\u00fado usando um script Lua. Pegamos a vari\u00e1vel da engine <code>remote_addr<\/code> e a inserimos no <code>string.format<\/code>. \u00c9 a mesma coisa que <code>sprintf<\/code>, apenas em Lua, apenas correto. E entregamos ao cliente.<\/p>\n<p>O resultado vai ficar assim:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/9f1aaf6625f1fe5904b1e8a568fac76d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nMas vamos voltar ao mundo real. Na produ\u00e7\u00e3o, ningu\u00e9m implanta Hello World. Normalmente, nossa aplica\u00e7\u00e3o acessa um banco de dados ou algo assim e passa a maior parte do tempo aguardando uma resposta.<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/485f713c0284e16b0817500c8606c104.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEla simplesmente fica esperando. Isso n\u00e3o \u00e9 muito bom. Quando chegam 100.000 usu\u00e1rios, fica muito dif\u00edcil para n\u00f3s. Por isso, vamos criar um exemplo de um aplicativo simples. Vamos buscar imagens, por exemplo, de gatinhos. Mas n\u00e3o vamos buscar simplesmente, vamos expandir as palavras-chave e, se o usu\u00e1rio procurar \"gatinhos\", vamos encontrar gatinhos, felinos e outros. Para come\u00e7ar, precisamos obter os dados da solicita\u00e7\u00e3o no backend. Isso fica assim:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/a2134f86f15764745ae8330f63185367.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nDuas linhas permitem que voc\u00ea recupere os par\u00e2metros GET, sem dificuldades. A seguir, vamos supor que, a partir de um banco de dados com uma tabela por palavra-chave e extens\u00e3o, recuperamos essa informa\u00e7\u00e3o atrav\u00e9s de um comando SQL. \u00c9 tudo simples. Ele se parece com isto:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/4543685dc907f30bba2a079a0fadad2c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nConectamos a biblioteca <code>resty.mysql<\/code>, que j\u00e1 temos no pacote. N\u00e3o precisamos instalar nada, est\u00e1 tudo pronto. Indicamos como nos conectar e fazemos a consulta SQL:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/2234b3a5b2e1d8efafec00a49f1a13b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAqui \u00e9 um pouco assustador, mas tudo funciona. Aqui, 10 \u00e9 o limite. Estamos recuperando 10 registros, somos pregui\u00e7osos, n\u00e3o queremos mostrar mais. Esqueci de mencionar o limite no SQL.<\/p>\n<p>Em seguida, encontramos imagens para todas as consultas. Reunimos um conjunto de consultas e preenchedemos uma tabela Lua chamada <code>reqs<\/code>, e fazemos <code>ngx.location.capture_multi<\/code>.<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/c18171845b3bd3872c4a7a7feae0d4bc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTodas essas consultas s\u00e3o feitas em paralelo, e recebemos as respostas. O tempo de execu\u00e7\u00e3o \u00e9 igual ao tempo da resposta mais lenta. Se todos respondem em 50 milissegundos, e enviamos cem consultas, a resposta chegar\u00e1 em 50 milissegundos.<\/p>\n<p>Como somos pregui\u00e7osos e n\u00e3o queremos escrever o processamento HTTP e cache, faremos com que o NGINX fa\u00e7a tudo por n\u00f3s. Como voc\u00ea viu, havia uma consulta para <code>url\/fetch<\/code>, aqui est\u00e1:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/ef8fcc6905b2860a7f214c41251582a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nFazemos um simples <code>proxy_pass<\/code>, indicamos onde armazenar em cache, como fazer isso, e tudo funciona.<\/p>\n<p>Mas isso n\u00e3o \u00e9 suficiente, ainda precisamos enviar os dados ao usu\u00e1rio. A ideia mais simples \u00e9 serializar tudo em JSON, facilmente, em duas linhas. Definimos o Content-Type, entregamos o JSON.<\/p>\n<p>Mas h\u00e1 uma dificuldade: o usu\u00e1rio n\u00e3o quer ler JSON. Precisamos envolver os desenvolvedores front-end. \u00c0s vezes, n\u00e3o estamos muito a fim de fazer isso no come\u00e7o. E os especialistas em SEO dir\u00e3o que, se estamos procurando imagens, isso n\u00e3o importa para eles. Mas se estamos fornecendo algum conte\u00fado, eles dir\u00e3o que os buscadores n\u00e3o indexam nada.<\/p>\n<p>O que fazer com isso? Claro, iremos enviar HTML ao usu\u00e1rio. Gerar manualmente n\u00e3o \u00e9 adequado, ent\u00e3o queremos usar modelos. Para isso, existe a biblioteca <code>lua-resty-template<\/code>.<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/66a6cffc402575d286cb00d138dc201a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVoc\u00ea provavelmente notou as tr\u00eas letras assustadoras OPM. O OpenResty vem com seu pr\u00f3prio gerenciador de pacotes, atrav\u00e9s do qual podemos instalar um monte de outros m\u00f3dulos, em particular, <code>lua-resty-template<\/code>. Este \u00e9 um motor de templates simples, semelhante ao Django templates. \u00c9 poss\u00edvel escrever c\u00f3digo e fazer substitui\u00e7\u00e3o de vari\u00e1veis.<\/p>\n<p>Como resultado, tudo ficar\u00e1 com esta apar\u00eancia:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/b54497e4f1ab5a80183dc49c172a7f15.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nCompilamos os dados e renderizamos o modelo novamente em duas linhas. O usu\u00e1rio est\u00e1 feliz, recebeu gatinhos. Como ampliamos a consulta, ele tamb\u00e9m recebeu uma foca. Vai saber, talvez ele estivesse procurando exatamente isso, mas n\u00e3o conseguia formular seu pedido corretamente.<\/p>\n<p>Tudo \u00e9 \u00f3timo, mas estamos em desenvolvimento e ainda n\u00e3o queremos mostrar aos usu\u00e1rios. Vamos implementar a autentica\u00e7\u00e3o. Para isso, vamos ver como o NGINX lida com a requisi\u00e7\u00e3o em termos de OpenResty:<\/p>\n<ul>\n<li>A primeira fase \u2014 <strong>access<\/strong>, quando o usu\u00e1rio acaba de chegar, e analisamos os cabe\u00e7alhos, o endere\u00e7o IP, e outros dados. Podemos imediatamente bloquear o usu\u00e1rio se n\u00e3o gostarmos dele. Isso pode ser usado para autentica\u00e7\u00e3o ou, se recebermos muitas requisi\u00e7\u00f5es, pode ser f\u00e1cil bloque\u00e1-las nesta fase.<\/li>\n<li><strong>rewrite<\/strong>. Reescrevemos alguns dados da requisi\u00e7\u00e3o.<\/li>\n<li><strong>conte\u00fado<\/strong>. Entregamos o conte\u00fado ao usu\u00e1rio.<\/li>\n<li><strong>filtro de cabe\u00e7alhos<\/strong>. Alteramos os cabe\u00e7alhos da resposta. Se usarmos <code>proxy_pass<\/code>, podemos reescrever alguns cabe\u00e7alhos antes de entreg\u00e1-los ao usu\u00e1rio.<\/li>\n<li><strong>filtro de corpo<\/strong>. Podemos alterar o corpo.<\/li>\n<li><strong>registro<\/strong>\u00a0\u2014 logging. Podemos escrever logs no elasticsearch sem uma camada adicional.<\/li>\n<\/ul>\n<p>\nNosso sistema de autentica\u00e7\u00e3o ser\u00e1 aproximadamente assim:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/f6c16665b75ce0fa0ee69e07ab6a4a61.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nVamos adicionar isso \u00e0quele <code>localiza\u00e7\u00e3o<\/code>, que descrevemos anteriormente, e colocar o seguinte c\u00f3digo l\u00e1:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/126d8411c92afa92f3c4f5b9791b3e9c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nVerificamos se temos o cookie token. Se n\u00e3o houver, redirecionamos para a autentica\u00e7\u00e3o. Os usu\u00e1rios s\u00e3o espertos e podem adivinhar que precisam colocar o cookie token. Portanto, tamb\u00e9m o armazenaremos no Redis:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/b876372412d648885c2f7d53e712a85b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nO c\u00f3digo para trabalhar com Redis \u00e9 muito simples e n\u00e3o difere de outras linguagens. Al\u00e9m disso, toda a entrada\/sa\u00edda, tanto l\u00e1 quanto aqui, \u00e9 n\u00e3o bloqueante. Se voc\u00ea escrever c\u00f3digo s\u00edncrono, ele funcionar\u00e1 de maneira ass\u00edncrona. \u00c9 um pouco como com gevent, mas bem feito.<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/74066c9c750c718f368617faacbe0acc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVamos implementar a autentica\u00e7\u00e3o:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/0b3b486ca3c417716ebdaac189bfdcbf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nDizemos que precisamos ler o corpo da requisi\u00e7\u00e3o. Obtemos os argumentos POST, verificamos se o login e a senha est\u00e3o corretos. Se estiverem incorretos, redirecionamos para a autentica\u00e7\u00e3o. Se estiverem corretos, gravamos o token no Redis:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/bcf470d84791b6d1d01152d5ad511dbd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nN\u00e3o esque\u00e7amos de definir o cookie, isso tamb\u00e9m \u00e9 feito em duas linhas:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo\" src=\"\/wp-content\/uploads\/2020\/02\/efe06a113de28bacd14b26d6bb62a037.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEste \u00e9 um exemplo simples e hipot\u00e9tico. Claro, n\u00e3o pretendemos fazer um servi\u00e7o que mostre gatinhos \u00e0s pessoas. Mas quem pode nos julgar? Portanto, vamos revisar o que pode ser feito em produ\u00e7\u00e3o.<\/p>\n<ul>\n<li><strong>Um backend minimalista<\/strong>. \u00c0s vezes, precisamos fornecer apenas um pouco de dados no backend: em algumas situa\u00e7\u00f5es, precisamos inserir uma data, em outras, exibir uma lista, informar quantos usu\u00e1rios est\u00e3o no site, conectar um contador ou estat\u00edsticas. Algo pequeno assim. \u00c9 muito f\u00e1cil configurar fragmentos m\u00ednimos. Isso pode ser feito rapidamente, de forma simples e eficaz.\n<\/li>\n<li><strong>Pr\u00e9-processamento de dados<\/strong>. \u00c0s vezes, queremos integrar an\u00fancios em nossa p\u00e1gina, e esses an\u00fancios s\u00e3o obtidos atrav\u00e9s de solicita\u00e7\u00f5es de API. Isso \u00e9 muito f\u00e1cil de fazer aqui. N\u00e3o sobrecarregamos nosso backend, que j\u00e1 trabalha arduamente. Podemos simplesmente montar aqui. Podemos juntar alguns JS ou, ao contr\u00e1rio, separ\u00e1-los, pr\u00e9-processando algo antes de entreg\u00e1-lo ao usu\u00e1rio.\n<\/li>\n<li><strong>Facade para microservi\u00e7o<\/strong>. Este tamb\u00e9m \u00e9 um \u00f3timo caso, que j\u00e1 implementei. Antes, trabalhei na empresa Tenzor, que lida com relat\u00f3rios eletr\u00f4nicos e fornece relat\u00f3rios para cerca da metade das pessoas jur\u00eddicas no pa\u00eds. Criamos um servi\u00e7o onde muitos recursos foram desenvolvidos usando esse mesmo mecanismo: roteamento, autentica\u00e7\u00e3o e mais.<br \/>\nOpenResty pode ser usado como a cola para seus microservi\u00e7os, proporcionando acesso unificado a tudo e uma interface comum. Como os microservi\u00e7os podem ser escritos em diferentes linguagens, como Node.js, PHP, Python ou at\u00e9 mesmo Erlang, entendemos que n\u00e3o queremos reescrever o mesmo c\u00f3digo em todos os lugares. Por isso, o OpenResty pode ser implementado na frente.<\/p>\n<\/li>\n<li><strong>Estat\u00edsticas e an\u00e1lises<\/strong>. Normalmente, o NGINX est\u00e1 na entrada, e todas as solicita\u00e7\u00f5es passam por ele. \u00c9 aqui que \u00e9 muito conveniente coletar dados. Podemos calcular algo imediatamente e enviar para algum lugar, por exemplo, Elasticsearch, Logstash ou simplesmente registrar em um log e depois encaminhar.\n<\/li>\n<li><strong>Sistemas multiusu\u00e1rio<\/strong>. Por exemplo, jogos online tamb\u00e9m s\u00e3o muito bem feitos. Hoje, em Cape Town, Alexander Gladish vai falar sobre como prototipar rapidamente um jogo multiplayer usando o OpenResty.\n<\/li>\n<li><strong>Filtragem de solicita\u00e7\u00f5es (WAF)<\/strong>. Atualmente, \u00e9 tend\u00eancia criar firewalls de aplica\u00e7\u00f5es web, e h\u00e1 muitos servi\u00e7os que os oferecem. Com o OpenResty, voc\u00ea pode criar um firewall de aplica\u00e7\u00f5es web que filtra solicita\u00e7\u00f5es conforme suas necessidades de forma simples e r\u00e1pida. Se voc\u00ea est\u00e1 usando Python, sabe que o PHP n\u00e3o ser\u00e1 injetado, a menos que voc\u00ea o inicie a partir do console em algum lugar. Voc\u00ea sabe que est\u00e1 usando MySQL e Python. Provavelmente, podem tentar realizar um directory traversal e injetar algo no banco de dados. Portanto, \u00e9 poss\u00edvel filtrar solicita\u00e7\u00f5es suspeitas de maneira r\u00e1pida e econ\u00f4mica logo na frente.\n<\/li>\n<li><strong>Comunidade.<\/strong> Como o OpenResty \u00e9 baseado no NGINX, ele tem uma vantagem: \u00e9 <strong>a comunidade NGINX<\/strong>. Ela \u00e9 muito grande, e boa parte das quest\u00f5es que voc\u00ea pode ter no in\u00edcio j\u00e1 foram resolvidas pela comunidade NGINX.\n<p><strong>Desenvolvedores Lua<\/strong>. Ontem conversei com alguns colegas que participaram do dia de aprendizado do HighLoad++ e fiquei sabendo que apenas o Tarantool foi escrito em Lua. Isso n\u00e3o \u00e9 verdade, pois muitas coisas foram feitas em Lua. Exemplos: OpenResty, servidor XMPP Prosody, motor de jogo Love2D, Lua \u00e9 usada em Warcraft e em outros lugares. Existem muitos desenvolvedores Lua, e eles t\u00eam uma comunidade grande e receptiva. Todas as minhas d\u00favidas sobre Lua foram resolvidas em quest\u00e3o de horas. Quando voc\u00ea escreve na lista de discuss\u00f5es, em poucos minutos j\u00e1 tem uma enxurrada de respostas explicando as coisas. Isso \u00e9 incr\u00edvel. Infelizmente, nem sempre a comunidade \u00e9 t\u00e3o amig\u00e1vel em outros lugares.<br \/>\nH\u00e1 um GitHub para o OpenResty, onde voc\u00ea pode abrir um issue se algo n\u00e3o estiver funcionando. H\u00e1 uma lista de discuss\u00e3o no Google Groups, onde \u00e9 poss\u00edvel discutir quest\u00f5es gerais, e h\u00e1 uma lista em chin\u00eas \u2014 caso voc\u00ea n\u00e3o domine o ingl\u00eas, mas saiba chin\u00eas.<\/li>\n<\/ul>\n<p><\/p>\n<h1>Resultados<\/h1>\n<p><\/p>\n<ul>\n<li>Espero ter conseguido transmitir que o OpenResty \u00e9 um framework muito conveniente voltado para a web.<\/li>\n<li>Ele tem uma baixa barreira de entrada, pois o c\u00f3digo \u00e9 semelhante ao que usamos, e a linguagem \u00e9 bastante simples e minimalista.<\/li>\n<li>Ele fornece I\/O ass\u00edncrono sem callbacks, n\u00e3o teremos o emaranhado que \u00e0s vezes podemos criar no NodeJS.<\/li>\n<li>Ele tem um deploy f\u00e1cil, pois s\u00f3 precisamos do NGINX com o m\u00f3dulo necess\u00e1rio e nosso c\u00f3digo, e tudo funciona imediatamente.<\/li>\n<li>Uma grande e receptiva comunidade.<\/li>\n<\/ul>\n<p>\nN\u00e3o entrei em detalhes sobre como a roteiriza\u00e7\u00e3o \u00e9 feita, teria sido uma explica\u00e7\u00e3o muito longa.<\/p>\n<p>Obrigado pela aten\u00e7\u00e3o!<\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"silrEB0Brvo\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/silrEB0Brvo\/hqdefault.jpg\" alt=\"Por que no hosting comum a administra\u00e7\u00e3o do PrestaShop \u00e9 lenta, e no seu n\u00e3o \u00e9?\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\n<em><noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2016\/abstracts\/2432.html\">Vladimir Protasov - OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo<\/a><\/noindex><\/em><br \/>\n<br \/>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/321864\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u044b \u0432\u043d\u043e\u0432\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0441 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 HighLoad++ 2016, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043b\u0430 \u0432 \u043f\u043e\u0434\u043c\u043e\u0441\u043a\u043e\u0432\u043d\u043e\u043c \u0421\u043a\u043e\u043b\u043a\u043e\u0432\u043e 7\u20148 \u043d\u043e\u044f\u0431\u0440\u044f \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0433\u043e\u0434\u0430. \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u041f\u0440\u043e\u0442\u0430\u0441\u043e\u0432 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c NGINX \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e OpenResty \u0438 Lua. \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u043c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u041f\u0440\u043e\u0442\u0430\u0441\u043e\u0432, \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 Parallels. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0447\u0443\u0442\u044c-\u0447\u0443\u0442\u044c \u043e \u0441\u0435\u0431\u0435. \u0422\u0440\u0438 \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u0438 \u0441\u0432\u043e\u0435\u0439 \u0436\u0438\u0437\u043d\u0438 \u044f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u0442\u0435\u043c, \u0447\u0442\u043e \u043f\u0438\u0448\u0443 \u043a\u043e\u0434. \u0421\u0442\u0430\u043b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":71379,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-71378","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041c\u044b \u0432\u043d\u043e\u0432\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47OpenResty: \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c NGINX \u0432 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u044b \u0432\u043d\u043e\u0432\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-25T17:45:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-03T13:14:21+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47OpenResty: transformando o NGINX em um servidor de aplica\u00e7\u00f5es completo | ProHoster","description":"Estamos publicando novamente a transcri\u00e7\u00e3o.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47OpenResty: \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c NGINX \u0432 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 | ProHoster","og:description":"\u041c\u044b \u0432\u043d\u043e\u0432\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-25T17:45:02+00:00","article:modified_time":"2020-03-03T13:14:21+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"71378","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:03:22","updated":"2022-09-30 08:39:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/71378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=71378"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/71378\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/71379"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=71378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=71378"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=71378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}