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

Как диагностировать спорадические проблемы с производительностью?

У меня есть веб-приложение с очень разным временем отклика, и я не могу понять, что это вызывает.

Это (довольно сложная) установка:

Мощный выделенный сервер (i7, 32 ГБ ОЗУ) в немецком центре обработки данных, работающий под управлением Debian 6 с Proxmox. На этом хосте есть контейнер OpenVZ, настроенный на использование 2 ядер ЦП и 2 ГБ ОЗУ. В этом контейнере я запускаю Ubuntu 12.04 и экземпляр Redmine (приложение Rails).

Redmine используется с Apache 2 через Phusion Passenger.

Конфигурация Apache vhost (контейнер):

<VirtualHost *:80>
  ServerName redmine.somedomain.com
  DocumentRoot /var/www/redmine/
  <Directory "/var/www/redmine/">
RailsBaseURI /
PassengerResolveSymlinksInDocumentRoot on
Options FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
  </Directory>
  RewriteEngine On
  # Check for maintenance file and redirect all requests
  RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
  RewriteCond %{SCRIPT_FILENAME} !maintenance.html
  RewriteRule ^.*$ /system/maintenance.html [L]

  # Rewrite index to check for static
  RewriteRule ^/$ /cache/index.html [QSA]

  # Rewrite to check for Rails cached page
  RewriteRule ^([^.]+)$ /cache/$1.html [QSA]

  ErrorLog /var/log/apache2/redmine.error.log
  CustomLog /var/log/apache2/redmine.access.log combined

  ServerSignature Off
</VirtualHost>

Конфигурация пассажира:

<IfModule mod_passenger.c>
  PassengerRoot /var/lib/gems/1.9.1/gems/passenger-3.0.19
  PassengerRuby /usr/bin/ruby
  PassengerDefaultUser redmine
  PassengerDefaultGroup redmine
  PassengerPoolIdleTime 0
  PassengerMinInstances 4
  PassengerMaxPoolSize 10

  PassengerStatThrottleRate 600
  RailsFrameworkSpawnerIdleTime 0
  RailsAppSpawnerIdleTime 0
</IfModule>

Контейнерная виртуальная машина не имеет внешнего IP-адреса, поэтому на хосте я использую прокси-сервер Apache (обратный).

Конфигурация для этого (хост):

<VirtualHost *:443>
ServerName redmine.somedomain.com
SSLProxyEngine On
ProxyRequests off
ProxyPreserveHost on
ProxyPass / http://192.168.2.101/ keepalive=on max=100
ProxyPassReverse / http://192.168.2.101/

SSLEngine on
SSLCertificateFile /data/private/101/etc/apache2/ssl/redmine.crt
SSLCertificateKeyFile /data/private/101/etc/apache2/ssl/redmine.key
SSLCACertificatePath /data/private/101/etc/ssl/certs/

RequestHeader set X_FORWARDED_PROTO 'https'

KeepAlive On
KeepAliveTimeout 60

<Proxy *>
      Order allow,deny
      Allow from all
</Proxy>
ErrorLog /var/log/apache2/redmine.err.log

LogFormat "%t \"%r\" %D" measure-time
CustomLog /var/log/apache2/redmine.time.log measure-time
</VirtualHost>

Как вы можете видеть здесь, я активировал журнал по времени, чтобы узнать, как ведут себя отдельные запросы. Судя по тому журналу, это кажется довольно случайным.

Пример содержимого этого файла журнала:

[10/Feb/2014:09:48:36 +0100] "GET /plugin_assets/redmine_contacts_helpdesk/stylesheets/helpdesk.css?1377871228 HTTP/1.1" 501
...
[10/Feb/2014:09:48:35 +0100] "GET /plugin_assets/redmine_contacts_helpdesk/stylesheets/helpdesk.css?1377871228 HTTP/1.1" 20994933
...
[10/Feb/2014:09:49:07 +0100] "GET /plugin_assets/redmine_contacts_helpdesk/stylesheets/helpdesk.css?1377871228 HTTP/1.1" 418

Последнее значение - это время (в мкс), которое потребовалось для обработки запроса. Как вы можете видеть здесь, обычно для его обслуживания требуется всего около 500 мкс, но тот же самый запрос может занять до 20 секунд через минуту. На мой взгляд, это должно исключить процесс Ruby как возможную причину. Эта гипотеза подтверждается тем фактом, что во время таких медленных запросов сервер не показывает никакой нагрузки (будь то ЦП или ввод-вывод). Это также не зависит от нагрузки других виртуальных машин на хосте. Кажется совершенно случайным.

Из-за конкретной настройки существует множество возможных причин, и я действительно не знаю, с чего начать.

Может быть, кто-нибудь с большим опытом работы с задействованными компонентами подскажет, как подойти к диагностике этой проблемы.