RHEL Nginx SSL versus desempenho não SSL diferença enorme.

3

Estou no processo de configurar um proxy reverso Nginx 1.8.

Resumindo -

O tráfego HTTP de conteúdo HTML é até 50x mais rápido que o HTTPS.

O tráfego HTTP ProxyPass é até 7x mais rápido que o HTTPS.

o SO é RHEL7

Hardware:

2 core VMWare Intel(R) Xeon(R) CPU E5-2609 v3 @ 1.90GHz
cpu MHz         : 1897.802
cache size      : 15360 KB
bogomips        : 3795.60
1 Gbit network card

O cliente de benchmarking é o banco de dados Apache, a 1 hop away, ping 1ms. O banco de dados do Apache usa o seguinte protocolo TLS ao executar:

TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256

Certificado SSL do servidor RSA de 2048 bits. O grampeamento OCSP está ativado e é verificado.

/etc/sysctl.conf tem

net.ipv4.ip_local_port_range=1024 65000
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=15
net.core.netdev_max_backlog=4096
net.core.rmem_max=16777216
net.core.somaxconn=4096
net.core.wmem_max=16777216
net.ipv4.tcp_max_syn_backlog=20480
net.ipv4.tcp_max_tw_buckets=400000
net.ipv4.tcp_no_metrics_save=1
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_syn_retries=2
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_wmem=4096 65536 16777216
vm.min_free_kbytes=65536

/etc/security/limits.conf tem

nginx   soft    nofile  65536
nginx   hard    nofile  65536

O Nginx está configurado com

server {
  listen 443 ssl deferred backlog=1024;
  listen 80 deferred backlog=1024;

  server_name SERVERNAME;

  client_max_body_size 10m;

  ssl_stapling on;
  ssl_stapling_verify on;
  ssl_trusted_certificate path_to_/certificateAndChain.cer;
  ssl_certificate path_to_/certificateAndChain.cer;
  ssl_certificate_key path_to_/private.key;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers "EECDH+AES:EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:AES128+EECDH:D$
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:32m;
  ssl_session_timeout 1m;

  #resolver 8.8.8.8 8.8.8.4 valid=1m;
  #resolver_timeout 5s;

  location / {
   proxy_pass_header Server;
   proxy_set_header Host $http_host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $remote_addr;
   proxy_set_header X-Scheme $scheme;
   proxy_connect_timeout 43200000;
   proxy_read_timeout 43200000;
   proxy_send_timeout 43200000;
   proxy_buffering off;
   proxy_http_version 1.1;
   proxy_set_header Connection "";

   proxy_pass http://IPADDRESS/;

  }

  location /localtest {
    root /var/www/localtest;
    index index.html;
  }
}

Resultados reais:

Exibição de conteúdo HTML local HTTP

ab -c200 -n20000 http://SERVERNAME/localtest/index.html
Requests per second:    12751.64 [#/sec] (mean)
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    4   2.3      4      11
Processing:     2   12   7.3      9      96
Waiting:        1   10   7.7      7      96
Total:          2   16   6.6     14     100

HTTPS:

Requests per second:    252.28 [#/sec] (mean)
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       12  651 288.1    694    1470
Processing:     0  141 134.4    101    1090
Waiting:        0  101 124.3     65    1089
Total:         15  792 276.7    809    1641

Proxying para o Apache, 1ms ping, 1 hop away.

HTTP

Requests per second:    1584.88 [#/sec] (mean)
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   2.3      1       8
Processing:     4  141 309.6     30    1244
Waiting:        4  141 309.7     29    1244
Total:         10  143 310.3     31    1248

HTTPS

Requests per second:    215.99 [#/sec] (mean)
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       14 1131 622.3   1137    2030
Processing:     4  474 413.2    313    1814
Waiting:        1  399 405.6    257    1679
Total:         26 1605 769.6   1699    3306
    
por arek 06.02.2016 / 14:41

2 respostas

7

Os benchmarks são mentiras, não refletem a realidade, mas podem ser uma ferramenta útil para detectar gargalos. Mas você tem que entender os benchmarks. Como você omite os detalhes essenciais necessários para entender os resultados do benchmark, pode ser que você não entenda o que pode afetar os resultados do benchmark.

Especialmente, informações sobre o tamanho da carga útil do teste e as informações detalhadas da carga da CPU para o servidor e o cliente estão ausentes. Assim, pode ser que você já esteja atingindo os limites de CPU no cliente ou no servidor. Também pode ser principalmente um problema das viagens mais redondas que você precisa para as solicitações. Vamos explicar os aspectos do HTTP versus HTTPS em mais detalhes:

ab -c200 -n20000 http://SERVERNAME/localtest/index.html

Você configurou para usar 200 solicitações simultâneas. O tamanho da solicitação é desconhecido, portanto, podemos supor que haverá apenas carga útil mínima. Você também não está usando nenhum HTTP keep alive, o que significa que haverá uma nova conexão TCP para cada solicitação. Eu duvido que o banco de apache esteja fazendo a retomada da sessão TLS para que haja um handshake completo a cada vez. O que te dá:

  • HTTP: 1 RTT para o handshake TCP e outro RTT para uma solicitação e resposta HTTP mínima. Isso também pode incluir a conexão fechar já (dependente da implementação). Isso significa 2 RTT e transferência mínima de dados.
  • O HTTPS adiciona isso:

    • 2 RTT para um handshake TLS completo e provavelmente também 1 RTT para o encerramento do TLS. Apenas por causa de um total de 5 RTT para HTTPS vs. 2 RTT para HTTP simples você deve ver uma grande queda no desempenho, ou seja, de cerca de 13000 req / s para 5200 req / s (ou seja, 2/5).
    • Os dados transferidos para o handshake TLS podem ser maiores do que o que você tem como carga dentro de sua solicitação HTTP simples (Editar: com base no tamanho do valor de suas respostas varia de 60 bytes a 50 KB, provavelmente não é isso relevante).
    • Mas você também tem muitos cálculos para o handshake TLS, tanto no cliente quanto no lado do servidor. E mais, porque você está usando o ECDHE, consulte o link .

Os cálculos durante o handshake de TLS precisam de muito tempo de CPU e é por isso que seria importante fornecer informações sobre a carga da CPU. Pode ser que você esteja simplesmente atingindo o máximo que a CPU pode fazer, seja no servidor ou no cliente. Por favor, note também que o banco de dados do apache é de encadeamento único, então seria suficiente para maximizar o desempenho de um único núcleo de CPU, mesmo se os outros estivessem ociosos. E mesmo se você usar vários segmentos, o cálculo ainda leva tempo. Usar openssl speed não reflete o que realmente é feito dentro do handshake TLS e também testa apenas a velocidade máxima com um único encadeamento, não com vários cálculos em paralelo e todo o cache de lixo etc. envolvido.

Assim, embora isso possa ser uma referência interessante para ver o que é possível, isso não reflete a realidade na maioria dos casos. O fato é que o TLS pode reduzir muito o desempenho, mas com o tráfego HTTP comum, você terá solicitações maiores, o HTTP mantido ativo e a reutilização da sessão TLS, o que reduz o impacto do dispendioso handshake TLS.

Mas se o benchmark for realmente limitado no desempenho do servidor e não no desempenho do cliente, a configuração pode refletir servidores usados para rastreamento, onde você pode ter apenas uma pequena resposta (ou seja, 1x1 pixel) de vários sites diferentes sem nenhum tipo de reutilização de sessão TLS ou HTTP manter-se ativo.

    
por 06.02.2016 / 15:51
0

A solicitação do FIRST https é realmente mais lenta por causa da negociação do TLS, e seu benchmark apenas testa isso.

Um cliente da vida real fará muitas solicitações (uma para a página html e várias para js / css / images).

Com os tickets de sessão TLS, essa negociação TLS é ignorada após a primeira solicitação.

Até a expiração do ticket da sessão, os pedidos de https serão um pouco mais lentos que o http. Mas se você usar SPDY ou HTTP2, https será mais rápido que http.

    
por 07.02.2016 / 11:12