{"id":35106,"date":"2019-10-31T22:02:22","date_gmt":"2019-10-31T19:02:22","guid":{"rendered":"https:\/\/prohoster.info\/blog\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie\/"},"modified":"2019-10-31T22:02:22","modified_gmt":"2019-10-31T19:02:22","slug":"proizvoditelnost-setevyh-prilozhenij-linux-vvedenie","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie","title":{"rendered":"Desempenho de aplicativos de rede no Linux. Introdu\u00e7\u00e3o.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>As aplica\u00e7\u00f5es web s\u00e3o agora utilizadas em todo lugar, e entre todos os protocolos de transporte, o HTTP ocupa a maior parte. Ao estudar as nuances do desenvolvimento de aplica\u00e7\u00f5es web, muitos costumam prestar pouca aten\u00e7\u00e3o ao sistema operacional onde essas aplica\u00e7\u00f5es realmente s\u00e3o executadas. A separa\u00e7\u00e3o entre desenvolvimento (Dev) e opera\u00e7\u00f5es (Ops) apenas agravava a situa\u00e7\u00e3o. Mas com a dissemina\u00e7\u00e3o da cultura DevOps, os desenvolvedores come\u00e7aram a assumir a responsabilidade pelo lan\u00e7amento de suas aplica\u00e7\u00f5es na nuvem, portanto, para eles, \u00e9 muito \u00fatil se familiarizar completamente com o back-end do sistema operacional. Isso \u00e9 especialmente \u00fatil se voc\u00ea est\u00e1 tentando implantar um sistema para milhares ou dezenas de milhares de conex\u00f5es simult\u00e2neas.<\/p>\n<p>As limita\u00e7\u00f5es em servi\u00e7os web s\u00e3o muito semelhantes \u00e0s limita\u00e7\u00f5es em outros aplicativos. Seja em balanceadores de carga ou servidores de banco de dados, todos esses aplicativos enfrentam problemas semelhantes em um ambiente de alto desempenho. Compreender essas limita\u00e7\u00f5es fundamentais e as maneiras de super\u00e1-las permitir\u00e1, em geral, avaliar o desempenho e a escalabilidade de suas aplica\u00e7\u00f5es web.<\/p>\n<p>Estou escrevendo esta s\u00e9rie de artigos em resposta \u00e0s perguntas de jovens desenvolvedores que desejam se tornar arquitetos de sistemas bem informados. N\u00e3o \u00e9 poss\u00edvel entender claramente os m\u00e9todos de otimiza\u00e7\u00e3o de aplica\u00e7\u00f5es Linux sem mergulhar nos fundamentos de como elas funcionam no n\u00edvel do sistema operacional. Embora existam muitos tipos de aplica\u00e7\u00f5es, neste ciclo quero explorar aplica\u00e7\u00f5es de rede, e n\u00e3o de desktop, como navegadores ou editores de texto. Este material \u00e9 voltado para desenvolvedores e arquitetos que desejam entender como programas Linux ou Unix funcionam e como estrutur\u00e1-los para um alto desempenho.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nLinux \u00e9 <i>um sistema operacional<\/i> , e na maioria das vezes suas aplica\u00e7\u00f5es rodam exatamente neste SO. Embora eu diga \"Linux\", na maior parte do tempo, voc\u00ea pode presumir com seguran\u00e7a que me refiro a todos os sistemas operacionais semelhantes ao Unix como um todo. No entanto, eu n\u00e3o testei o c\u00f3digo associado em outros sistemas. Ent\u00e3o, se voc\u00ea est\u00e1 interessado em FreeBSD ou OpenBSD, o resultado pode variar. Quando eu experimento algo espec\u00edfico do Linux, fa\u00e7o quest\u00e3o de apontar isso.<\/p>\n<p>Embora voc\u00ea possa usar os conhecimentos adquiridos para criar um aplicativo do zero e torn\u00e1-lo perfeitamente otimizado, \u00e9 melhor n\u00e3o fazer isso. Se voc\u00ea escrever um servidor web em C ou C++ para um aplicativo comercial da sua organiza\u00e7\u00e3o, provavelmente ser\u00e1 seu \u00faltimo dia no trabalho. No entanto, conhecer a estrutura desses aplicativos ajudar\u00e1 na escolha de programas j\u00e1 existentes. Voc\u00ea poder\u00e1 comparar sistemas baseados em processos com sistemas baseados em threads, bem como com sistemas baseados em eventos. Voc\u00ea entender\u00e1 e apreciar\u00e1 por que o Nginx funciona melhor do que o Apache httpd e por que um aplicativo Python baseado em Tornado pode atender mais usu\u00e1rios em compara\u00e7\u00e3o a um aplicativo Python baseado em Django.<\/p>\n<h1>ZeroHTTPd: ferramenta de aprendizado<\/h1>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/shuveb\/zerohttpd\">ZeroHTTPd<\/a><\/noindex>\u00a0\u2014 um servidor web que eu escrevi do zero em C como ferramenta de aprendizado. Ele n\u00e3o possui depend\u00eancias externas, incluindo acesso ao Redis. N\u00f3s executamos nossas pr\u00f3prias rotinas Redis. Veja mais detalhes abaixo.<\/p>\n<p>Embora pud\u00e9ssemos discutir a teoria por muito tempo, n\u00e3o h\u00e1 nada melhor do que escrever c\u00f3digo, execut\u00e1-lo e comparar todas as arquiteturas de servidor entre si. Esse \u00e9 o m\u00e9todo mais visual. Portanto, vamos escrever um servidor web simples, o ZeroHTTPd, aplicando cada modelo: baseado em processos, threads e eventos. Vamos testar cada um desses servidores e ver como eles funcionam em compara\u00e7\u00e3o uns com os outros. O ZeroHTTPd \u00e9 implementado em um \u00fanico arquivo C. O servidor baseado em eventos consiste em <noindex><a rel=\"nofollow\" href=\"https:\/\/troydhanson.github.io\/uthash\/\">uthash<\/a><\/noindex>, uma excelente implementa\u00e7\u00e3o de tabela hash que vem em um \u00fanico arquivo de cabe\u00e7alho. Nos demais casos, n\u00e3o h\u00e1 depend\u00eancias para manter o projeto simples.<\/p>\n<p>O c\u00f3digo cont\u00e9m muitos coment\u00e1rios para ajudar a entender. Sendo um servidor web simples composto de algumas linhas de c\u00f3digo, o ZeroHTTPd tamb\u00e9m representa um framework m\u00ednimo para desenvolvimento web. Ele tem funcionalidade limitada, mas \u00e9 capaz de servir arquivos est\u00e1ticos e p\u00e1ginas 'din\u00e2micas' muito simples. Devo dizer que o ZeroHTTPd \u00e9 bastante adequado para ensinar como criar aplica\u00e7\u00f5es Linux de alto desempenho. No geral, a maioria dos servi\u00e7os web aguarda solicita\u00e7\u00f5es, verifica-as e as processa. Isso \u00e9 exatamente o que o ZeroHTTPd far\u00e1. \u00c9 uma ferramenta de aprendizado, e n\u00e3o para produ\u00e7\u00e3o. Ele n\u00e3o \u00e9 forte em tratamento de erros e dificilmente se destacar\u00e1 nas melhores pr\u00e1ticas de seguran\u00e7a (oh sim, eu usei <code>strcpy<\/code>) ou com truques complicados da linguagem C. Mas espero que ele fa\u00e7a bem seu trabalho.<\/p>\n<p><img decoding=\"async\" alt=\"Desempenho de aplicativos de rede no Linux. Introdu\u00e7\u00e3o.\" src=\"\/wp-content\/uploads\/33fd0a5353667001523d5d4c8ada9ecf.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>P\u00e1gina inicial do ZeroHTTPd. Ele pode servir diferentes tipos de arquivos, incluindo imagens.<\/i><\/p>\n<h1>Aplicativo de livro de visitas<\/h1>\n<p>\nAplicativos web modernos geralmente n\u00e3o se limitam a arquivos est\u00e1ticos. Eles t\u00eam intera\u00e7\u00f5es complexas com v\u00e1rias bases de dados, caches, etc. Portanto, vamos criar um aplicativo web simples chamado \"Livro de Visitas\", onde os visitantes podem deixar mensagens sob seus nomes. No livro de visitas, as mensagens anteriores s\u00e3o armazenadas. Tamb\u00e9m h\u00e1 um contador de visitantes na parte inferior da p\u00e1gina.<\/p>\n<p><img decoding=\"async\" alt=\"Desempenho de aplicativos de rede no Linux. Introdu\u00e7\u00e3o.\" src=\"\/wp-content\/uploads\/ed8e828e8567d3d114875520988742d7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Aplicativo web \"Livro de Visitas\" ZeroHTTPd<\/i><\/p>\n<p>O contador de visitantes e as mensagens do livro de visitas s\u00e3o armazenados no Redis. Para a comunica\u00e7\u00e3o com o Redis, implementamos procedimentos pr\u00f3prios, que n\u00e3o dependem de bibliotecas externas. N\u00e3o sou um grande f\u00e3 de escrever c\u00f3digo caseiro quando existem solu\u00e7\u00f5es p\u00fablicas bem testadas. Mas o objetivo do ZeroHTTPd \u00e9 estudar o desempenho do Linux e o acesso a servi\u00e7os externos, enquanto o processamento de solicita\u00e7\u00f5es HTTP impacta seriamente o desempenho. Precisamos ter controle total sobre as comunica\u00e7\u00f5es com o Redis em cada uma de nossas arquiteturas de servidor. Em uma arquitetura, usamos chamadas bloqueantes, em outras, procedimentos baseados em eventos. Usar uma biblioteca cliente externa do Redis n\u00e3o nos dar\u00e1 esse controle. Al\u00e9m disso, nosso pequeno cliente Redis realiza apenas algumas fun\u00e7\u00f5es (obter, definir e incrementar uma chave; obter e adicionar a um array). Al\u00e9m disso, o protocolo Redis \u00e9 incrivelmente elegante e simples. N\u00e3o \u00e9 necess\u00e1rio estud\u00e1-lo especificamente. O fato de que todo o trabalho do protocolo \u00e9 realizado em cerca de cem linhas de c\u00f3digo demonstra qu\u00e3o bem pensado ele \u00e9.<\/p>\n<p>Na pr\u00f3xima ilustra\u00e7\u00e3o, s\u00e3o mostradas as a\u00e7\u00f5es do aplicativo quando o cliente (navegador) faz uma solicita\u00e7\u00e3o <code>\/guestbookURL<\/code>.<\/p>\n<p><img decoding=\"async\" alt=\"Desempenho de aplicativos de rede no Linux. Introdu\u00e7\u00e3o.\" src=\"\/wp-content\/uploads\/5c5e6740419384b7232aeead95db491b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Mecanismo de funcionamento do aplicativo livro de visitas<\/i><\/p>\n<p>Quando precisamos exibir a p\u00e1gina do livro de visitas, ocorre uma chamada ao sistema de arquivos para ler o modelo na mem\u00f3ria e tr\u00eas chamadas de rede ao Redis. O arquivo do modelo cont\u00e9m a maior parte do conte\u00fado HTML para a p\u00e1gina na captura de tela acima. Tamb\u00e9m existem marcadores especiais para a parte din\u00e2mica do conte\u00fado: postagens e contador de visitantes. N\u00f3s os obtemos do Redis, inserimos na p\u00e1gina e entregamos ao cliente o conte\u00fado totalmente formado. A terceira chamada ao Redis pode ser evitada, pois o Redis retorna um novo valor da chave ao ser incrementada. No entanto, para o nosso servidor com uma arquitetura ass\u00edncrona baseada em eventos, muitas chamadas de rede representam um bom desafio em termos de aprendizado. Assim, descartamos o valor retornado pelo Redis sobre o n\u00famero de visitantes e o solicitamos em uma chamada separada.<\/p>\n<h1>Arquiteturas de Servidor ZeroHTTPd<\/h1>\n<p>\nEstamos construindo sete vers\u00f5es do ZeroHTTPd com funcionalidade id\u00eantica, mas arquiteturas diferentes:<\/p>\n<ul>\n<li>Iterativa\n<\/li>\n<li>Servidor Fork (um processo filho por solicita\u00e7\u00e3o)\n<\/li>\n<li>Servidor Pr\u00e9-Fork (forking de processos antecipado)\n<\/li>\n<li>Servidor com Threads (um thread por solicita\u00e7\u00e3o)\n<\/li>\n<li>Servidor com Threads Pr\u00e9-Criadas\n<\/li>\n<li>Arquitetura baseada em <code>poll()<\/code>\n<\/li>\n<li>Arquitetura baseada em <code>epoll<\/code><\/li>\n<\/ul>\n<p>\nMedimos o desempenho de cada arquitetura, sobrecarregando o servidor com requisi\u00e7\u00f5es HTTP. Mas ao comparar arquiteturas com alto grau de paralelismo, o n\u00famero de requisi\u00e7\u00f5es aumenta. Testamos tr\u00eas vezes e calculamos a m\u00e9dia.<\/p>\n<h1>Metodologia de Teste<\/h1>\n<p>\n<img decoding=\"async\" alt=\"Desempenho de aplicativos de rede no Linux. Introdu\u00e7\u00e3o.\" src=\"\/wp-content\/uploads\/aa4f337b6e90fa032fbef5374fac8f53.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Configura\u00e7\u00e3o para Teste de Carga do ZeroHTTPd<\/i> <\/p>\n<p>\u00c9 importante que, ao executar os testes, todos os componentes n\u00e3o estejam em uma \u00fanica m\u00e1quina. Nesse caso, o sistema operacional tem custos indiretos adicionais de agendamento, pois os componentes competem pelo CPU. Medir os custos indiretos do sistema operacional com cada uma das arquiteturas de servidor escolhidas \u00e9 um dos objetivos mais importantes deste exerc\u00edcio. Adicionar mais vari\u00e1veis seria prejudicial ao processo. Portanto, a configura\u00e7\u00e3o na imagem acima funciona melhor.<\/p>\n<h3>O que cada um desses servidores faz<\/h3>\n<p><\/p>\n<ul>\n<li>load.unixism.net: aqui executamos <code>ab<\/code>, a ferramenta Apache Benchmark. Ela gera a carga necess\u00e1ria para testar nossas arquiteturas de servidor.\n<\/li>\n<li>nginx.unixism.net: \u00e0s vezes queremos executar mais de uma inst\u00e2ncia de um programa de servidor. Para isso, o servidor Nginx com configura\u00e7\u00f5es apropriadas funciona como um balanceador de carga, recebendo <i>ab<\/i> para nossos processos de servidor.\n<\/li>\n<li>zerohttpd.unixism.net: aqui executamos nossos programas de servidor em sete arquiteturas diferentes, uma por vez.\n<\/li>\n<li>redis.unixism.net: neste servidor, o daemon Redis est\u00e1 em execu\u00e7\u00e3o, onde s\u00e3o armazenados registros do livro de visitas e a contagem de visitantes.<\/li>\n<\/ul>\n<p>\nTodos os servidores funcionam em um n\u00facleo de processador. A ideia \u00e9 avaliar o desempenho m\u00e1ximo de cada uma das arquiteturas. Como todos os programas de servidor s\u00e3o testados em hardware id\u00eantico, esse \u00e9 o n\u00edvel b\u00e1sico para sua compara\u00e7\u00e3o. Minha instala\u00e7\u00e3o de teste consiste em servidores virtuais alugados da Digital Ocean.<\/p>\n<h3>O que estamos medindo?<\/h3>\n<p>\nPodemos medir diferentes m\u00e9tricas. Avaliamos o desempenho de cada arquitetura nesta configura\u00e7\u00e3o, carregando os servidores com solicita\u00e7\u00f5es em diferentes n\u00edveis de paralelismo: a carga aumenta de 20 a 15.000 usu\u00e1rios simult\u00e2neos.<\/p>\n<h1>Resultados dos testes<\/h1>\n<p>\nNo gr\u00e1fico a seguir, \u00e9 mostrado o desempenho dos servidores em diferentes arquiteturas em v\u00e1rios n\u00edveis de paralelismo. No eixo y est\u00e3o as solicita\u00e7\u00f5es por segundo, e no eixo x, as conex\u00f5es paralelas.<\/p>\n<p><img decoding=\"async\" alt=\"Desempenho de aplicativos de rede no Linux. Introdu\u00e7\u00e3o.\" src=\"\/wp-content\/uploads\/3415bcfb66503152d644130f68bd19da.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Desempenho de aplicativos de rede no Linux. Introdu\u00e7\u00e3o.\" src=\"\/wp-content\/uploads\/ba457b671eb758f3226e0eeafaadc6aa.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Desempenho de aplicativos de rede no Linux. Introdu\u00e7\u00e3o.\" src=\"\/wp-content\/uploads\/aea06856d61d4d4bdda9814c53a28d4a.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAbaixo est\u00e1 uma tabela com os resultados.<\/p>\n<p> solicita\u00e7\u00f5es por segundo <\/p>\n<p><strong>paralelismo<\/strong><br \/>\n<strong>iterativa.<\/strong><br \/>\n<strong>fork<\/strong><br \/>\n<strong>pr\u00e9-fork<\/strong><br \/>\n<strong>multithread<\/strong><br \/>\n<strong>pr\u00e9-multithread<\/strong><br \/>\n<strong>poll<\/strong><br \/>\n<strong>epoll<\/strong><\/p>\n<p>20<br \/>\n7<br \/>\n112<br \/>\n2100<br \/>\n1800<br \/>\n2250<br \/>\n1900<br \/>\n2050<\/p>\n<p>50<br \/>\n7<br \/>\n190<br \/>\n2200<br \/>\n1700<br \/>\n2200<br \/>\n2000<br \/>\n2000<\/p>\n<p>100<br \/>\n7<br \/>\n245<br \/>\n2200<br \/>\n1700<br \/>\n2200<br \/>\n2150<br \/>\n2100<\/p>\n<p>200<br \/>\n7<br \/>\n330<br \/>\n2300<br \/>\n1750<br \/>\n2300<br \/>\n2200<br \/>\n2100<\/p>\n<p>300<br \/>\n\u2013<br \/>\n380<br \/>\n2200<br \/>\n1800<br \/>\n2400<br \/>\n2250<br \/>\n2150<\/p>\n<p>400<br \/>\n\u2013<br \/>\n410<br \/>\n2200<br \/>\n1750<br \/>\n2600<br \/>\n2000<br \/>\n2000<\/p>\n<p>500<br \/>\n\u2013<br \/>\n440<br \/>\n2300<br \/>\n1850<br \/>\n2700<br \/>\n1900<br \/>\n2212<\/p>\n<p>600<br \/>\n\u2013<br \/>\n460<br \/>\n2400<br \/>\n1800<br \/>\n2500<br \/>\n1700<br \/>\n2519<\/p>\n<p>700<br \/>\n\u2013<br \/>\n460<br \/>\n2400<br \/>\n1600<br \/>\n2490<br \/>\n1550<br \/>\n2607<\/p>\n<p>800<br \/>\n\u2013<br \/>\n460<br \/>\n2400<br \/>\n1600<br \/>\n2540<br \/>\n1400<br \/>\n2553<\/p>\n<p>900<br \/>\n\u2013<br \/>\n460<br \/>\n2300<br \/>\n1600<br \/>\n2472<br \/>\n1200<br \/>\n2567<\/p>\n<p>1000<br \/>\n\u2013<br \/>\n475<br \/>\n2300<br \/>\n1700<br \/>\n2485<br \/>\n1150<br \/>\n2439<\/p>\n<p>1500<br \/>\n\u2013<br \/>\n490<br \/>\n2400<br \/>\n1550<br \/>\n2620<br \/>\n900<br \/>\n2479<\/p>\n<p>2000<br \/>\n\u2013<br \/>\n350<br \/>\n2400<br \/>\n1400<br \/>\n2396<br \/>\n550<br \/>\n2200<\/p>\n<p>2500<br \/>\n\u2013<br \/>\n280<br \/>\n2100<br \/>\n1300<br \/>\n2453<br \/>\n490<br \/>\n2262<\/p>\n<p>3000<br \/>\n\u2013<br \/>\n280<br \/>\n1900<br \/>\n1250<br \/>\n2502<br \/>\ngrande varia\u00e7\u00e3o<br \/>\n2138<\/p>\n<p>5000<br \/>\n\u2013<br \/>\ngrande varia\u00e7\u00e3o<br \/>\n1600<br \/>\n1100<br \/>\n2519<br \/>\n\u2013<br \/>\n2235<\/p>\n<p>8000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n1200<br \/>\ngrande varia\u00e7\u00e3o<br \/>\n2451<br \/>\n\u2013<br \/>\n2100<\/p>\n<p>10\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\ngrande varia\u00e7\u00e3o<br \/>\n\u2013<br \/>\n2200<br \/>\n\u2013<br \/>\n2200<\/p>\n<p>11\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n2200<br \/>\n\u2013<br \/>\n2122<\/p>\n<p>12\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n970<br \/>\n\u2013<br \/>\n1958<\/p>\n<p>13\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n730<br \/>\n\u2013<br \/>\n1897<\/p>\n<p>14\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n590<br \/>\n\u2013<br \/>\n1466<\/p>\n<p>15\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n532<br \/>\n\u2013<br \/>\n1281<\/p>\n<p>\nA partir do gr\u00e1fico e da tabela, fica claro que acima de 8000 solicita\u00e7\u00f5es simult\u00e2neas, restam apenas dois competidores: pr\u00e9-fork e epoll. Com o aumento da carga, o servidor baseado em poll se comporta pior do que o multithread. A arquitetura de cria\u00e7\u00e3o pr\u00e9via de threads compete de forma digna com epoll: isso demonstra o qu\u00e3o bem o n\u00facleo do Linux gerencia um grande n\u00famero de threads.<\/p>\n<h1>C\u00f3digo fonte do ZeroHTTPd<\/h1>\n<p>\nC\u00f3digo fonte do ZeroHTTPd <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/shuveb\/zerohttpd\">aqui<\/a><\/noindex>. Para cada arquitetura, h\u00e1 um diret\u00f3rio separado.<\/p>\n<pre>ZeroHTTPd\n\u2502\n\u251c\u2500\u2500 01_iterative\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 02_forking\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 03_preforking\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 04_threading\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 05_prethreading\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 06_poll\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 07_epoll\n\u2502    \u2514\u2500\u2500 main.c\n\u251c\u2500\u2500 Makefile\n\u251c\u2500\u2500 public\n\u2502   \u251c\u2500\u2500 index.html\n\u2502   \u2514\u2500\u2500 tux.png\n\u2514\u2500\u2500 templates\n    \u2514\u2500\u2500 guestbook\n        \u2514\u2500\u2500 index.html<\/pre>\n<p>\nAl\u00e9m das sete diret\u00f3rios para todas as arquiteturas, h\u00e1 mais duas no diret\u00f3rio de n\u00edvel superior: public e templates. Na primeira, est\u00e1 o arquivo index.html e a imagem da primeira captura de tela. Voc\u00ea pode colocar outros arquivos e pastas l\u00e1, e o ZeroHTTPd deve fornecer esses arquivos est\u00e1ticos sem problemas. Se o caminho no navegador corresponder ao caminho na pasta public, o ZeroHTTPd procura o arquivo index.html nesse diret\u00f3rio. O conte\u00fado do livro de visitas \u00e9 gerado dinamicamente. Ele tem apenas a p\u00e1gina principal, e seu conte\u00fado \u00e9 baseado no arquivo 'templates\/guestbook\/index.html'. \u00c9 f\u00e1cil adicionar p\u00e1ginas din\u00e2micas ao ZeroHTTPd para expans\u00e3o. A ideia \u00e9 que os usu\u00e1rios podem adicionar templates a esse diret\u00f3rio e expandir o ZeroHTTPd conforme necess\u00e1rio.<\/p>\n<p>Para compilar todos os sete servidores, inicie <code>make all<\/code> a partir do diret\u00f3rio raiz \u2014 e todas as compila\u00e7\u00f5es aparecer\u00e3o neste diret\u00f3rio. Os arquivos execut\u00e1veis buscam os diret\u00f3rios public e templates a partir do diret\u00f3rio de onde s\u00e3o executados.<\/p>\n<h1>API do Linux<\/h1>\n<p>\nPara entender as informa\u00e7\u00f5es neste ciclo de artigos, n\u00e3o \u00e9 necess\u00e1rio ter um bom conhecimento da API do Linux. No entanto, recomendo ler mais sobre o tema, h\u00e1 muitos recursos dispon\u00edveis na rede. Embora abordemos v\u00e1rias categorias da API do Linux, nossa aten\u00e7\u00e3o se concentrar\u00e1 principalmente em processos, threads, eventos e na pilha de rede. Al\u00e9m de livros e artigos sobre a API do Linux, recomendo tamb\u00e9m consultar as p\u00e1ginas de manual para chamadas de sistema e fun\u00e7\u00f5es de biblioteca utilizadas.<\/p>\n<h1>Desempenho e escalabilidade<\/h1>\n<p>\nUma observa\u00e7\u00e3o sobre desempenho e escalabilidade. Teoricamente, n\u00e3o h\u00e1 conex\u00e3o entre os dois. Voc\u00ea pode ter um servi\u00e7o web que funcione muito bem, com um tempo de resposta de alguns milissegundos, mas que n\u00e3o escalone de forma alguma. Da mesma forma, pode haver um aplicativo web de baixo desempenho que leva v\u00e1rios segundos para responder, mas que escala para dezenas, para lidar com dezenas de milhares de usu\u00e1rios simult\u00e2neos. No entanto, a combina\u00e7\u00e3o de alto desempenho e escalabilidade \u00e9 uma combina\u00e7\u00e3o poderosa. Aplicativos de alto desempenho consomem recursos de forma econ\u00f4mica e, assim, atendem de maneira eficaz a mais usu\u00e1rios simult\u00e2neos em um servidor, reduzindo custos.<\/p>\n<h1>Tarefas de CPU e I\/O<\/h1>\n<p>\nFinalmente, nas computa\u00e7\u00f5es, existem sempre dois tipos poss\u00edveis de tarefas: para I\/O e CPU. Receber solicita\u00e7\u00f5es pela internet (entrada e sa\u00edda de rede), gerenciamento de arquivos (entrada e sa\u00edda de rede e disco), intera\u00e7\u00f5es com o banco de dados (entrada e sa\u00edda de rede e disco) \u2014 todas essas s\u00e3o a\u00e7\u00f5es de I\/O. Algumas consultas ao banco de dados podem sobrecarregar um pouco a CPU (ordena\u00e7\u00e3o, c\u00e1lculo da m\u00e9dia de milh\u00f5es de resultados, etc.). A maioria dos aplicativos da web tem um limite para o I\/O m\u00e1ximo, enquanto a CPU raramente \u00e9 utilizada em sua plena capacidade. Quando voc\u00ea v\u00ea que uma tarefa de entrada e sa\u00edda est\u00e1 utilizando muita CPU, isso geralmente indica uma arquitetura de aplicativo ruim. Isso pode significar que os recursos da CPU est\u00e3o sendo desperdi\u00e7ados em gerenciamento de processos e troca de contexto \u2014 e isso n\u00e3o \u00e9 muito \u00fatil. Se voc\u00ea estiver fazendo algo como processamento de imagens, convers\u00e3o de arquivos de \u00e1udio ou aprendizado de m\u00e1quina, ent\u00e3o o aplicativo exigir\u00e1 recursos robustos de CPU. Mas para a maioria dos aplicativos, isso n\u00e3o \u00e9 o caso.<\/p>\n<h1>Mais sobre arquiteturas de servidores<\/h1>\n<p><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-i-iterative-servers\/\">Parte I. Arquitetura Iterativa<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-ii-forking-servers\/\">Parte II. Servidores Fork<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-iii-preforked-servers\/\">Parte III. Servidores Pr\u00e9-fork<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-iv-threaded-servers\/\">Parte IV. Servidores com Threads de Execu\u00e7\u00e3o<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-v-pre-threaded-servers\/\">Parte V. Servidores com Cria\u00e7\u00e3o Antecipada de Threads<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-vi-polling-servers\/\">Parte VI. Arquitetura Baseada em Poll<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-vii-epoll-servers\/\">Parte VII. Arquitetura Baseada em Epoll<\/a><\/noindex><\/li>\n<\/ol>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/455212\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u044b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e, \u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u043b\u044c\u0432\u0438\u043d\u0443\u044e \u0434\u043e\u043b\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 HTTP. \u0418\u0437\u0443\u0447\u0430\u044f \u043d\u044e\u0430\u043d\u0441\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0443\u0434\u0435\u043b\u044f\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u0430\u043b\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0433\u0434\u0435 \u044d\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f. \u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (Dev) \u0438 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 (Ops) \u043b\u0438\u0448\u044c \u0443\u0445\u0443\u0434\u0448\u0430\u043b\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e. \u041d\u043e \u0441 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u044b DevOps \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u043d\u0435\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35106","post","type-post","status-publish","format-standard","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=\"\u0412\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u044b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e, \u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u043b\u044c\u0432\u0438\u043d\u0443\u044e \u0434\u043e\u043b\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 HTTP.\" \/>\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\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie\" \/>\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\udd47\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 Linux. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u044b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e, \u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u043b\u044c\u0432\u0438\u043d\u0443\u044e \u0434\u043e\u043b\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 HTTP.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie\" \/>\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=\"2019-10-31T19:02:22+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:02:22+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\udd47Desempenho de Aplica\u00e7\u00f5es de Rede Linux. Introdu\u00e7\u00e3o | ProHoster","description":"Os aplicativos da web s\u00e3o amplamente utilizados atualmente, e entre todos os protocolos de transporte, o HTTP ocupa a maior parte.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie","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\udd47\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 Linux. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 | ProHoster","og:description":"\u0412\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u044b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e, \u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u043b\u044c\u0432\u0438\u043d\u0443\u044e \u0434\u043e\u043b\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 HTTP.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie","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":"2019-10-31T19:02:22+00:00","article:modified_time":"2019-10-31T19:02:22+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35106","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":"2026-01-21 21:51:33","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:09:55","updated":"2026-01-21 21:51:33","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\/35106","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=35106"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/35106\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=35106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=35106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=35106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}