Назад | Перейти на главную страницу

HTTPS более чем в 50 раз медленнее, чем HTTP

У меня есть веб-сайт, который использует https для передачи файла javascript клиенту. Сайт getsimpleapps.com.

Оказывается, этот файл загружается в 52 раза медленнее с https (20,08–29,08 с), чем с http (380 мс).

Домашняя страница сайта работает так же медленно, как файл javacript.

Недавно я переключился с Dreamhost на linode и пытался заставить SSL работать на новом сервере, пока это не произошло. Никаких сумасшедших настроек я не делал.

Линод работает под управлением Ubuntu 12.04, а сайт находится на вершине стека (LAMP).

Мой вопрос к сообществу переполнения стека: как мне исправить SSL и HTTPS на моем сервере? Я знаю, что переполнение стека усеяно вопросами относительно медленность HTTPS но реальных решений не дается. Руководство по ubuntu или руководство по настройке было бы идеальным.


файл: /etc/apache2/sites-enabled/getsimpleapps.com

<VirtualHost *:80>
     ServerAdmin admin@getsimpleapps.com
     ServerName getsimpleapps.com
     ServerAlias www.getsimpleapps.com
     DocumentRoot /srv/sites/getsimpleapps.com/public/
     ErrorLog /srv/sites/getsimpleapps.com/logs/error.log
     CustomLog /srv/sites/getsimpleapps.com/logs/access.log combined
</VirtualHost>

<VirtualHost 50.116.58.18:443>
     SSLEngine On
     #SSLCertificateFile /etc/apache2/ssl/www.getsimpleapps.com.crt
     #SSLCertificateKeyFile /etc/apache2/ssl/www.getsimpleapps.com.key
     #SSLCACertificateFile /etc/apache2/ssl/comodo.crt
     SSLCertificateFile /etc/apache2/ssl/dreamhost/dh.crt
     SSLCertificateKeyFile /etc/apache2/ssl/dreamhost/dh.key
     SSLCACertificateFile /etc/apache2/ssl/dreamhost/dh.cer

     ServerAdmin admin@getsimpleapps.com
     ServerName getsimpleapps.com
     ServerAlias www.getsimpleapps.com
     DocumentRoot /srv/sites/getsimpleapps.com/public/
     ErrorLog /srv/sites/getsimpleapps.com/logs/error.log
     CustomLog /srv/sites/getsimpleapps.com/logs/access.log combined
</VirtualHost>

Curl с локальной рабочей станции

thomas@workstation:~$ time curl -Iv https://getsimpleapps.com/
* About to connect() to getsimpleapps.com port 443 (#0)
*   Trying 50.116.58.18... connected
* Connected to getsimpleapps.com (50.116.58.18) port 443 (#0)
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: OU=Domain Control Validated; OU=Provided by New Dream Network, LLC; OU=DreamHost Basic SSL; CN=getsimpleapps.com
*    start date: 2012-02-23 00:00:00 GMT
*    expire date: 2013-02-22 23:59:59 GMT
*    subjectAltName: getsimpleapps.com matched
*    issuer: C=GB; ST=Greater Manchester; L=Salford; O=Comodo CA Limited; CN=PositiveSSL CA
*    SSL certificate verify ok.
> HEAD / HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: getsimpleapps.com
> Accept: */*
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Thu, 02 Aug 2012 20:31:39 GMT
Date: Thu, 02 Aug 2012 20:31:39 GMT
< Server: Apache/2.2.22 (Ubuntu)
Server: Apache/2.2.22 (Ubuntu)
< X-Powered-By: PHP/5.3.10-1ubuntu3.2
X-Powered-By: PHP/5.3.10-1ubuntu3.2
< Set-Cookie: ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2298c7e45da25e4aaf80f7a1e36ed4a006%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%2250.75.209.154%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A81%3A%22curl%2F7.21.4+%28universal-apple-darwin11.0%29+libcurl%2F7.21.4+OpenSSL%2F0.9.8r+zlib%2F1.2.5%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1343939499%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D80bf8ae5040fc47780ccd59f1fb8b267; expires=Thu, 02-Aug-2012 22:31:39 GMT; path=/
Set-Cookie: ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2298c7e45da25e4aaf80f7a1e36ed4a006%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%2250.75.209.154%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A81%3A%22curl%2F7.21.4+%28universal-apple-darwin11.0%29+libcurl%2F7.21.4+OpenSSL%2F0.9.8r+zlib%2F1.2.5%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1343939499%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D80bf8ae5040fc47780ccd59f1fb8b267; expires=Thu, 02-Aug-2012 22:31:39 GMT; path=/
< Vary: Accept-Encoding
Vary: Accept-Encoding
< Content-Type: text/html
Content-Type: text/html

< 
* Connection #0 to host getsimpleapps.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):

real    0m29.078s
user    0m0.018s
sys 0m0.005s

Curl с сервера linode (через ssh)

thomas@vannevar:~$ time curl -Iv https://getsimpleapps.com/happy-ending/api/script.js?shop=holstee.myshopify.com
* About to connect() to getsimpleapps.com port 443 (#0)
*   Trying 50.116.58.18... connected
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: OU=Domain Control Validated; OU=Provided by New Dream Network, LLC; OU=DreamHost Basic SSL; CN=getsimpleapps.com
*    start date: 2012-02-23 00:00:00 GMT
*    expire date: 2013-02-22 23:59:59 GMT
*    subjectAltName: getsimpleapps.com matched
*    issuer: C=GB; ST=Greater Manchester; L=Salford; O=Comodo CA Limited; CN=PositiveSSL CA
*    SSL certificate verify ok.
> HEAD /happy-ending/api/script.js?shop=holstee.myshopify.com HTTP/1.1
> User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: getsimpleapps.com
> Accept: */*
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Thu, 02 Aug 2012 20:43:30 GMT
Date: Thu, 02 Aug 2012 20:43:30 GMT
< Server: Apache/2.2.22 (Ubuntu)
Server: Apache/2.2.22 (Ubuntu)
< X-Powered-By: PHP/5.3.10-1ubuntu3.2
X-Powered-By: PHP/5.3.10-1ubuntu3.2
< Set-Cookie: ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2204a54136cab08f9fdc5f082ebb8e739a%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A12%3A%2250.116.58.18%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A97%3A%22curl%2F7.22.0+%28i686-pc-linux-gnu%29+libcurl%2F7.22.0+OpenSSL%2F1.0.1+zlib%2F1.2.3.4+libidn%2F1.23+librtmp%2F2.3%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1343940210%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7De7d7b8e2ca69b34c531ba7472b4b21b7; expires=Thu, 02-Aug-2012 22:43:30 GMT; path=/
Set-Cookie: ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2204a54136cab08f9fdc5f082ebb8e739a%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A12%3A%2250.116.58.18%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A97%3A%22curl%2F7.22.0+%28i686-pc-linux-gnu%29+libcurl%2F7.22.0+OpenSSL%2F1.0.1+zlib%2F1.2.3.4+libidn%2F1.23+librtmp%2F2.3%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1343940210%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7De7d7b8e2ca69b34c531ba7472b4b21b7; expires=Thu, 02-Aug-2012 22:43:30 GMT; path=/
< Content-Type: text/javascript
Content-Type: text/javascript
* no chunk, no close, no size. Assume close to signal end

< 
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):

real    0m25.991s
user    0m0.015s
sys 0m0.022s

У меня была такая же проблема с почти идентичной разницей во времени ответа между HTTP и HTTPS. Оказывается, проблема была как в ответ от @htmltiger: Apache2 просто исчерпал рабочие процессы.

Это приводит к постановке новых запросов в очередь до тех пор, пока рабочий не освободится и не сможет обработать следующий [источник]. Я предполагаю, что причина, по которой это влияет только на HTTPS, а не также на HTTPS, заключается в том, что почти весь ваш трафик проходит через HTTP, а Apache дает HTTP и HTTPS-запросам одинаковый приоритет, принимая по одному запросу из каждой очереди по очереди. Поэтому, когда очередь HTTPS намного длиннее, запросы ждут намного дольше. Действительно, есть две очереди, поскольку очередь - это просто механизм очереди TCP-соединений Linux, а Linux предоставляет одну очередь на порт.

Диагностика

Если это ваша проблема, будут проявляться следующие симптомы:

  • Лучший индикатор: на вашем сервере, apachectl status показывает, что все допустимые рабочие процессы запущены. Это тот случай, когда нет точек . светятся в строке таблицы результатов процесса, указывая на то, что не осталось «открытой ячейки без текущего процесса». Строка может выглядеть, например, так:

    KKKKKKRKKKRRCWKKKCCKWKKKKCRCKKKKKKKCKCKKKKWRKKKKWRWKKKKKKCWKKWKKK
    
  • Вы видите подобные сообщения в своем основном журнале ошибок Apache2 (/var/log/apache2/error.log, а не для домена):

    [mpm_prefork:error] [pid 4715] AH00161: server reached MaxRequestWorkers 
        setting, consider raising the MaxRequestWorkers setting
    
  • В вашем бэклоге Apache много процессов. В соответствии с эта подробная статья, вы можете видеть это из unacked: ценность в ss -lti '( sport = :https )' вывод. В зависимости от версии или конфигурации ss, хотя это значение может отсутствовать.

  • Большая часть задержки (например, 17 из 20 с) отображается в сетевой консоли Firefox на вкладке «Время» для исходного запрошенного URL как «Блокировка».

Решение

Предполагается, что вы используете серверный модуль prefork MPM в Apache. Это похоже на модули MPM «событийный» и «рабочий» - подробности.

  1. редактировать /etc/apache2/mods-enabled/mpm_prefork.conf и увеличить MaxRequestWorkers настройка.

  2. Если вы увеличите его до значения по умолчанию 256, вам также необходимо установить ServerLimit на то же значение, чтобы изменение вступило в силу.

  3. Примените изменения: service apache2 reload

  4. Убедитесь, что на табло выводится apachectl status что новый MaxRequestWorkers настройка эффективна. Он должен быть эквивалентен длине строки табло в знаках.

  5. Если настройка еще не действует, выполните поиск в /etc/apache2 для старых директив конфигурации (и их еще более старых устаревших синонимов), которые могут перезаписать ваше изменение:

    grep -R MaxRequestWorkers /etc/apache2/*
    grep -R MaxClients /etc/apache2/*
    

Дифференциальный диагноз

Если вы видите, что HTTPS намного медленнее, чем HTTP, но не каждый раз в серии перезагрузок страницы (только в среднем), то у вас может быть вариант эта причудливая проблема, с двумя серверами Apache2, работающими на SSL-порту 443.

У меня была аналогичная проблема для загруженного сервера, но увеличение MaxRequestWorkers до 400 в mpm_prefork.conf исправило ее.

Попробуйте изменить шифр на RC4-MD5 (хороший баланс производительности и безопасности), то есть:

SSLCipherSuite RC4-MD5

Ура

Оказывается, моя проблема заключалась в том, что мои ключи были с другого сервера. Мне нужно было получить новый сертификат и настроить его с новыми ключами.