Nginx vs Apache - Existem comparações de uso e estatísticas reais por aí?

45

Eu tenho um novo servidor para jogar e estou olhando para uma tela em branco. Eu posso colocar o que eu quiser. Enquanto me sinto confortável com o Apache, continuo ouvindo como o nginx pode lidar com muito mais tráfego que o Apache, por fatores de 10, 100 e até mais. Não apenas isso é "muito, muito mais rápido".

Quando procuro artigos, encontro muitas coisas não relacionadas ao Drupal. Ou, quando me deparei com um artigo relacionado ao Drupal, é 1) o arquivo de configuração de alguém com uma rápida tentativa de explicar como configurá-lo, ou 2) alguém dizendo "não, não use o nginx, vá com o Apache com PHP fcgid "mas nunca há explicação sobre o porquê.

Então, quando se trata de Drupal, qual é a realidade aqui?

Como exemplo, estou procurando algo semelhante ao deste artigo 2bits.com . Aqui, o autor analisou bastante o Apache mod_php vs Apache com fcgid, ponderando os prós e os contras de cada um, e forneceu um estudo de caso para ilustrar o impacto no mundo real. Há informações suficientes neste artigo para que eu tome uma decisão informada sobre qual abordagem seria melhor para minha situação.

Enquanto esse autor compara mod_php a fcgid, estou procurando o mesmo tipo de visão abrangente e real do Apache vs Nginx.

Alguém mudou para o Nginx e ficou "deslumbrado" com a diferença que fez em relação ao Apache? Mesmo para ambientes altamente otimizados que já usam APC, Memcache e cache agressivo como o Varnish, quando a única variável que muda é a substituição do Apache pelo Nginx, faz a diferença suficiente por si só para merecer investir nessa tecnologia alternativa mais nova ?

O site que acessará esse servidor recebe uma média de 2 milhões de PV por mês. Pilha LAMP executando o Cent OS 6. CPU de 4 núcleos com 8 GIGS de ram. Memcached e APC farão parte do mix. Nada de especial na instalação do Drupal - basicamente o vanilla 7 com cerca de 50 módulos.

blue928
fonte
2
Se você deseja ajustar um site específico para obter desempenho, é melhor executar seus próprios testes do que depender do trabalho de outras pessoas. A combinação de usuários anônimos e usuários logados, por exemplo, é um fator importante. Se você olhar para as estatísticas de desempenho de um site que recebe principalmente tráfego anônimo, e o seu não é assim, você também não deve se incomodar. Mas se o seu site tiver um tráfego amplamente anônimo, na minha experiência, colocar o Varnish na frente do servidor da Web faz uma diferença muito maior do que o servidor que você executa por trás dele.
Alfred Armstrong

Respostas:

60

Estritamente falando, isso não responde à pergunta que você está fazendo. Espero que seja útil de qualquer maneira.

Apache / Nginx / Lighttpd / outro servidor web. Importa qual eu escolho? Em suma, não .

A resposta muito mais longa:

Se e somente se, você tem uma porcentagem muito grande de usuários fazendo login, caso se preocupe com o desempenho do servidor da web. Se seus usuários forem anônimos, qualquer diferença que você possa derivar, teoricamente, de otimizar nessas camadas empalidece absoluto em comparação com tornar seus recursos melhor armazenáveis ​​em cache. Se seus arquivos css tiverem cabeçalhos de cache adequados, o UA nem sequer os solicitará pela segunda vez. Aquilo importa. Se você pode armazenar em cache suas páginas no Varnish ou em uma solução de software semelhante, servir essa página é uma questão de fazer uma pesquisa de hash e retornar uma grande parte dos dados diretamente da RAM. Aquilo importa. Em ambos os cenários, o daemon HTTP nunca está envolvido, o PHP não é chamado. O Drupal não inicializa. Nenhum conjunto grande de módulos deve ser carregado na RAM, nenhuma consulta de banco de dados demorada é executada.

Quando você executa um carregamento completo da página, de um cache frio, para um usuário conectado, em uma página complexa; muitas coisas estão acontecendo. Sim, o servidor da web está envolvido em lidar com a solicitação recebida, configurando alguns cabeçalhos e devolvendo a resposta. Mas o tempo que leva, nem é relevante no contexto do Drupal executando uma inicialização completa e emitindo sua resposta. Pode haver centenas de consultas de banco de dados sendo executadas. Lógica altamente complexa em PHP é avaliada pelo analisador. Muitos módulos estão sendo carregados na RAM. Melhorar o desempenho de qualquer uma dessas coisas, é muito mais provável que dê uma contribuição séria ao desempenho.

Por uma questão de argumento: digamos que você gastou muito tempo otimizando todo o resto.

  1. Você executa o APC (Or Optimizer + ) e a versão mais recente e mais rápida do PHP.
  2. As consultas de banco de dados são poucas.
  3. A lógica do PHP foi reduzida.
  4. Você armazena em cache o que pode no verniz.
  5. Você reestruturou seu site inteiro para poder armazenar em cache muito do lado do cliente e fazer muito trabalho pesado no ECMAScript .

Se você possui muitos usuários conectados e já lidou com tudo isso acima, provavelmente pode fazer a diferença, mas otimizando o desempenho ou substituindo o servidor da web. No entanto, adivinhe. Seu site é tão complexo e os padrões de uso de seus usuários específicos são únicos . Não há resposta genérica. Você precisará configurar todos os servidores Web diferentes atrás de um balanceador de carga e ver como eles se comportam no seu cenário .

O exposto acima foi uma tentativa de logicamente chegar à conclusão de que gastar o desempenho do tempo otimizando o servidor da web provavelmente é um mau uso do tempo. Eu adoraria que alguém fizesse buracos no item acima, provavelmente aprenderia algo novo com isso. :)

Algumas outras notas:

  1. Durante a palestra da DrupalCon Copenhagen , o criador do PHP Rasmus Lerdorf , usando o próprio Nginx, falando sobre o tema da performance do Drupal, disse: "As pessoas sempre me perguntam sobre servidores da Web ... isso realmente não importa, o servidor da Web é praticamente irrelevante". . (Aproximadamente às 26:30 no vídeo)
  2. O Facebook passou inúmeras horas escrevendo o Hiphop , uma base de código significativamente maior que o próprio Drupal, para acelerar o código PHP em um "mísero" 100%. Examinei o Hiphop $ wc -l $(find . -type f | grep -v "^\.git" | grep -v "^\.hphp/third_party") | sort -nr | head -n1e constatei que ele consistia em 1.512.481 linhas de código. Essa é uma quantidade absolutamente insana de trabalho para melhorar a velocidade do PHP. Acho que é porque a velocidade do PHP é muito importante para eles.
  3. Eu mencionei que um bom armazenamento em cache terá um efeito muito maior do que o ajuste do servidor da web?
  4. Com o lançamento do Apache 2.4, Jim Jagielski basicamente afirma que o Apache 2.4 é mais rápido que os servidores baseados em eventos .
  5. Participei do Drupal Performance and Scalability no The Dream Team , onde apenas essa pergunta surgiu. Todas as respostas sobre as quais escolher não estavam relacionadas ao desempenho. Coisas como "Qual você já sabe configurar" e "Qual permitirá criar a pilha de tecnologia mais simples" foram alguns dos motivos mencionados para escolher o outro. O desempenho não apareceu na imagem.
Letharion
fonte
4
Não se esqueça da CDN para impedir que a grande maioria das solicitações de CSS, JS e imagem chegue ao servidor da Web.
mpdonadio
Excelente ponto! Acho que vou ter que reescrever drupal.stackexchange.com/questions/24180/… em algum momento. Uma discussão sobre o Apache / Nginx não parece ser o local ideal para criar uma lista abrangente de otimizações de desempenho.
Letharion
1
Esta é uma ótima resposta. Apenas um detalhe: você não deve usar "ECMAScript" e "JavaScript" de forma intercambiável. O JavaScript possui muito mais do que o ECMAScript.
Você está dizendo que o cache é muito mais importante que a velocidade do servidor da web. Adivinha? Se um servidor da web usar menos memória que o outro, você poderá usar mais RAM para armazenar em cache. Então, podemos dizer que é importante ajustar seu servidor da Web corretamente para que ele não consuma toda a sua RAM, certo?
Pqnet 29/08/14
Ajustar seu servidor para usar menos RAM é absolutamente bom, mas se você estiver tentando entrar em território de alto desempenho, provavelmente estará executando verniz em um servidor dedicado, para que seu servidor http e cache não estejam competindo pela mesma memória.
Letharion
32

OK, embora essa pergunta já tenha sido respondida, estou exigindo mais uma vez, principalmente porque não gosto das implicações dessas respostas que não fazem diferença e, como desenvolvedor da Web, odeio fazer cache com paixão .

A diferença entre o Apache e o nginx não é tanto "quão rápido eles podem atender a uma solicitação", mas quantas solicitações eles podem atender na mesma quantidade de hardware (especialmente com recursos limitados), o que é algo um pouco diferente.

O Apache é um servidor baseado em processo. Isso significa que bifurca um processo para cada solicitação. Nginx é um servidor baseado em eventos, ou seja, usa um loop de eventos (assíncrono) em vez de processos ou threads.

E enquanto um servidor baseado em processos (como o Apache) pode executar mais ou menos a par com um servidor assíncrono baseado em eventos (como o nginx) sob cargas leves, sob cargas mais pesadas, como por exemplo 10.000.000 pedidos simultâneos, o nginx usa apenas alguns megabytes de RAM, enquanto o Apache requer várias centenas de megabytes apenas para o servidor da web (sem incluir o aplicativo da web, que precisa de muito mais recursos), se é que poderia fazê-lo.

Portanto, sob cargas mais pesadas, você verá o Apache consumir muita memória RAM, o que sem surpresa diminui significativamente o desempenho.

Mais significativamente, um maior consumo de RAM significa que o Apache pode atender a menos solicitações no mesmo hardware que o nginx, o que significa que o Apache requer mais hardware para a mesma quantidade de usuários, o que significa que você tem um TCO mais alto (custo total de propriedade) com Apache do que com nginx, o que reduz seu ROI (retorno do investimento).

Memória total usada por X conexões simultâneas (menos é melhor)

Uso de memória

Solicitações que podem ser atendidas por segundo em X conexões simultâneas em 1 conjunto de hardware (mais é melhor)

Pedidos por segundo

Fonte: ApacheBench, por dreamhost.com

Veja também este artigo sobre oceano digital .
Aparentemente, isso depende da arquitetura de manipulação de conexão que você escolher para o Apache.

Dilema
fonte
6
Você bate na cabeça com "... não com a rapidez com que eles podem atender a uma solicitação, mas com quantos pedidos eles podem atender na mesma quantidade de hardware ..." . Dada uma máquina com exatamente o mesmo hardware e outras variáveis, se eu puder atender a 1.000.000 de usuários por dia com o nginx, em que o apache pode servir apenas 200.000, certamente a melhor opção, do ponto de vista dos custos, é o nginx. Dada uma certa configuração de hardware, você viu uma grande diferença entre o que o nginx pode fazer em comparação com o apache?
precisa saber é o seguinte
2
O Apache 2.4, a versão atual, possui um modelo baseado em evento: httpd.apache.org/docs/current/mod/event.html
Greg
1
Além disso, para quem diz que isso não importa, porque "tudo ficará bem enquanto você estiver armazenando coisas em cache": você sabe o que precisa fazer em cache? Você precisa de RAM grátis.
Pqnet 29/08/14
Frequentemente vejo essas afirmações gerais de "Nginx é mais impressionante", no entanto, raramente (nunca?) Vejo alguém apoiar isso com evidências sólidas. É sempre "Minha instância do nginx altamente configurada vence um servidor de estoque apache, então agora eu provei que sou legal porque uso o nginx como as outras crianças legais". O Nginx pode ser muito melhor que o Apache, pelo que sei, mas ainda tenho que ver alguém mostrar realmente que é esse o caso.
Letharion
@ Letharion: Feito (por dreamhost.com) e adicionado conforme sua solicitação. Como você pode ver nos resultados deste benchmark, o nginx é claramente mais eficiente em termos de memória. Também é provavelmente: minha instância stock-nginx venceu minha instância stock-Apache na mesma referência no mesmo computador.
Quandary
16

Eu mudo do Apache para o Nginx / PHP-FPM há alguns meses.

Fiz um teste comparativo com um site drupal e testei vários casos de uso. Em um servidor VPS com 1 CPU e 512 Mo RAM

Drupal com apenas cache

Nginx

ab -n 100 -c 30 xxx
Server Software:        nginx
Document Path:          /
Document Length:        24902 bytes

Concurrency Level:      30
Time taken for tests:   2.775 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      2529500 bytes
HTML transferred:       2490200 bytes
Requests per second:    36.04 [#/sec] (mean)
Time per request:       832.394 [ms] (mean)
Time per request:       27.746 [ms] (mean, across all concurrent requests)
Transfer rate:          890.28 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=10
Maximum connect burst length: 1

Total: connections 100 requests 1000 replies 1000 test-duration 48.946 s

Connection rate: 2.0 conn/s (489.5 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 470.6 avg 489.5 max 522.2 median 488.5 stddev 9.5
Connection time [ms]: connect 0.2
Connection length [replies/conn]: 10.000

Request rate: 20.4 req/s (48.9 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 20.0 avg 20.4 max 20.8 stddev 0.2 (9 samples)
Reply time [ms]: response 46.8 transfer 2.1
Reply size [B]: header 450.0 content 24902.0 footer 2.0 (total 25354.0)
Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 6.50 system 17.58 (user 13.3% system 35.9% total 49.2%)
Net I/O: 507.3 KB/s (4.2*10^6 bps)

Apache

ab -n 100 -c 30 xxx
Server Software:        Apache/2.2.16
Document Path:          /
Document Length:        24902 bytes

Concurrency Level:      30
Time taken for tests:   28.364 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      25346000 bytes
HTML transferred:       24902000 bytes
Requests per second:    35.26 [#/sec] (mean)
Time per request:       850.918 [ms] (mean)
Time per request:       28.364 [ms] (mean, across all concurrent requests)
Transfer rate:          872.66 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=10
Maximum connect burst length: 1

Total: connections 100 requests 1000 replies 1000 test-duration 52.261 s

Connection rate: 1.9 conn/s (522.6 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 499.0 avg 522.6 max 591.0 median 518.5 stddev 19.4
Connection time [ms]: connect 0.6
Connection length [replies/conn]: 10.000

Request rate: 19.1 req/s (52.3 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 18.2 avg 19.2 max 19.6 stddev 0.5 (10 samples)
Reply time [ms]: response 46.9 transfer 5.3
Reply size [B]: header 453.0 content 24902.0 footer 2.0 (total 25357.0)
Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 6.80 system 18.88 (user 13.0% system 36.1% total 49.1%)
Net I/O: 475.2 KB/s (3.9*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

Drupal com cache e impulso

Nginx

ab -n 10000 -c 30 xxx
Server Software:        nginx
Document Path:          /
Document Length:        25002 bytes

Concurrency Level:      30
Time taken for tests:   2.275 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      253780000 bytes
HTML transferred:       250020000 bytes
Requests per second:    4395.52 [#/sec] (mean)
Time per request:       6.825 [ms] (mean)
Time per request:       0.228 [ms] (mean, across all concurrent requests)
Transfer rate:          108934.95 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=1000 --num-calls=30
Maximum connect burst length: 1

Total: connections 1000 requests 30000 replies 30000 test-duration 5.971 s

Connection rate: 167.5 conn/s (6.0 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 4.2 avg 6.0 max 13.0 median 4.5 stddev 2.6
Connection time [ms]: connect 0.1
Connection length [replies/conn]: 30.000

Request rate: 5024.0 req/s (0.2 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 5017.2 avg 5017.2 max 5017.2 stddev 0.0 (1 samples)
Reply time [ms]: response 0.2 transfer 0.0
Reply size [B]: header 405.0 content 25002.0 footer 0.0 (total 25407.0)
Reply status: 1xx=0 2xx=30000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.79 system 2.56 (user 13.2% system 42.9% total 56.1%)
Net I/O: 125016.7 KB/s (1024.1*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

Apache

ab -n 1000 -c 30 xxxx
Server Software:        Apache/2.2.16
Document Path:          /
Document Length:        25002 bytes

Concurrency Level:      30
Time taken for tests:   0.753 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      25291000 bytes
HTML transferred:       25002000 bytes
Requests per second:    1327.92 [#/sec] (mean)
Time per request:       22.592 [ms] (mean)
Time per request:       0.753 [ms] (mean, across all concurrent requests)
Transfer rate:          32797.26 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=10
Maximum connect burst length: 1

Total: connections 100 requests 1000 replies 1000 test-duration 1.148 s

Connection rate: 87.1 conn/s (11.5 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 6.2 avg 11.5 max 14.1 median 11.5 stddev 1.3
Connection time [ms]: connect 0.1
Connection length [replies/conn]: 10.000

Request rate: 870.8 req/s (1.1 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 0.0 avg 0.0 max 0.0 stddev 0.0 (0 samples)
Reply time [ms]: response 1.1 transfer 0.1
Reply size [B]: header 260.0 content 25002.0 footer 0.0 (total 25262.0)
Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.13 system 0.57 (user 11.1% system 49.5% total 60.6%)
Net I/O: 21544.9 KB/s (176.5*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

referência para usuário autenticado (carregamento da página)

Nginx

Page load times : 2.85 s

Apache

Page load times : 5.4 s

Mas o poder do Nginx é o sistema de cache

Drupal sem Boost e Nginx com sistema de cache ativado

Server Software:        nginx
Document Path:          /
Document Length:        24902 bytes

Concurrency Level:      30
Time taken for tests:   2.437 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      252670000 bytes
HTML transferred:       249020000 bytes
Requests per second:    4103.34 [#/sec] (mean)
Time per request:       7.311 [ms] (mean)
Time per request:       0.244 [ms] (mean, across all concurrent requests)
Transfer rate:          101248.99 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=1000 --num-calls=30
Maximum connect burst length: 1

Total: connections 1000 requests 30000 replies 30000 test-duration 6.044 s

Connection rate: 165.5 conn/s (6.0 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 4.2 avg 6.0 max 11.7 median 4.5 stddev 2.6
Connection time [ms]: connect 0.1
Connection length [replies/conn]: 30.000

Request rate: 4963.7 req/s (0.2 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 4970.1 avg 4970.1 max 4970.1 stddev 0.0 (1 samples)
Reply time [ms]: response 0.2 transfer 0.0
Reply size [B]: header 405.0 content 25002.0 footer 0.0 (total 25407.0)
Reply status: 1xx=0 2xx=30000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.72 system 2.68 (user 12.0% system 44.3% total 56.3%)
Net I/O: 123516.8 KB/s (1011.8*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

Você deve usar a configuração do perusio Nginx for Drupal

flocondetoile
fonte
Como o Apache estava rodando, pré-forma, FCGI, etc? Sua configuração do Apache foi o mais otimizada possível quando você executou esses testes? O mesmo ambiente PHP estava em execução?
mpdonadio
O ambiente PHP (5.3) era exatamente o mesmo. Apache foi corrida mpm_prefork, e as configuração do Apache (maxclient, MaxSpareServers, MaxRequestsPerChild, etc) foi exactamente o mesmo do que o PHP5-FPM
flocondetoile
4
Estes são bons números, mas não tenho certeza se são uma comparação verdadeira. Apache + FastCGI vs Apache + FCGI + PHPFPM vs Nginx + PHPFPM mostrariam melhor as diferenças entre Apache e Nginx.
mpdonadio
Como o MPD aponta, essa não é uma comparação verdadeira. Você precisa estar executando o php-fpm nos dois para obter uma imagem verdadeira.
1
Nginx é uma boa opção para contas VPS limitadas por RAM, eu acho. Como ele pode operar confortavelmente com um espaço de RAM menor que o Apache - especialmente se você mantiver módulos desnecessários desinstalados - você tem mais RAM para executar caches de código de código (o APC ou o OpCache interno do PHP 5.5), forneça ao servidor MySQL / Postgres daemon um grande buffer e outras otimizações que Letharion aponta corretamente também são importantes.
Garrett Albright
0

Aqui está um teste de desempenho para dez servidores / variantes da Web (por exemplo, Apache, Nginx, lighttpd, Lightspeed, Hiawatha, Cherokee). Três dos testes estão relacionados ao Drupal.

Estou pensando que Hiawatha pode ser a melhor escolha geral. Supõe-se que tenha compatibilidade total com o Drupal , com ênfase na segurança (DoS, XSS, CSRF, prevenção de injeção de SQL) e em velocidades e dimensões semelhantes ao Nginx.

Em dois dos três testes do Drupal, Hiawatha e Nginx superam o Apache em cerca de 150%, mas no teste estático do Drupal, o Apache marginalmente supera o Nginx, enquanto Hiawatha supera o pacote em cerca de 10%.

Eu não penduraria meu chapéu em nenhum desses testes, mas ele oferece uma visão geral do desempenho em diferentes situações de uso. Eu acho que o desempenho por si só não deve ser a única consideração. Estabilidade e segurança podem ser os fatores mais importantes.

Hawkeye
fonte
0

Aqui estão os resultados dos testes de carga do drupal em execução no mesmo hardware, mas com diferentes servidores da web. (nginx e apache)

Aqui está a conclusão deste teste:

sob um grande tráfego com os mesmos recursos de hardware, o nginx tem um desempenho muito melhor que o apache.

wathmal
fonte