Тюнинг производительности и нагрузочное тестирование OTRS

Всем привет!

В этой статье собраны заметки как по нагрузочному тестированию OTRS, так и по различным способам, направленным на повышение производительности системы. Информация собрана из различных источников, приведенных в конце материала.

OTRS highload test

Общие принципы

Компоненты OTRS, рассматриваемые в процессе оптимизации производительности:

  • Apache Web Server (mod_perl) - сервер приложений
  • OTRS Framework (непосредственно сам OTRS) - приложение, исполняемое под Apache
  • База данных (в нашем примере - PostgreSQL)
  • Кэш бэкенда
OTRS components
Ключевые принципы, на которые стоит обращать внимание при построении высоконагруженной конфигурации OTRS:

  • Размещение веб-сервера Apache и базы данных на разных серверах
  • При нагрузке > 100 одновременно работающих пользователей рекомендуется использовать несколько серверов приложений, с балансировкой нагрузки при помощи nginx или DNS Round Robin.
  • Кэш OTRS (/opt/otrs/var/tmp) должен размещаться на высокопроизводительном дисковом разделе (предпочтительно SSD или ramdisk). Альтернативы - in-memory базы кэша (Redis или memcached).
Уместным также будет привести рекомендации для "объемных" конфигураций OTRS (large setups, >60 000 открытых тикетов):

  • Выбор Kernel::System::Ticket::IndexAccelerator::StaticDB в качестве TicketIndexModule
  • Тюнинг поискового индекса (Ticket Search Index)
  • В качестве хранилища вложений использовать файловую систему вместо базы (Kernel::System::Ticket::Article::Backend::MIMEBase::ArticleStorageFS). Если используется несколько серверов приложений, необходимо обеспечить общий доступ к файловому хранилищу (NFS / iSCSI).
Подробное описание настроек приведено в руководстве администратора.

Оптимальные настройки Apache Web Server

Обязательно использование модуля многопроцессовой обработки mpm_prefork. В Debian 9 веб-сервер Apache поставляется с включенным по-умолчанию mpm_event.

Проверить, какой модуль многопроцессности включен:

apachectl -t -D DUMP_MODULES | grep mpm
OTRS mpm_event
Отключить текущий модуль (на примере mpm_event, также может быть подключен mpm_worker) и включить mpm_prefork:

a2dismod mpm_event
a2enmod mpm_prefork
systemctl restart apache2


Проверить значения директив Apache (httpd.conf):

  • HostnameLookups Off - отключить запросы Apache к DNS
  • KeepAlive On - устанавливать постоянные соединения между сервером и клиентом. Экономия на повторной установке соединений.
  • KeepAliveTimeout 30
  • AllowOverride None - отключить использование .htaccess (рекомендуется прописывать настройки на уровне конфигураций виртуальных хостов)
  • MaxRequestsPerChild - сколько запросов может обработать дочерний поток (mpm_event, mpm_worker) или процесс (mpm_prefork) перед тем, как его нужно будет перезапустить. Помогает предотвратить утечки памяти. В конфигурационном файле OTRS уже прописано оптимальное значение - 4000, однако не лишним будет перепроверить.
Значения директив для mpm_prefork:

# Эти директивы позволяют заранее иметь в памяти созданные процессы, 
# чтобы не приходилось этого делать во время получения запроса
# При запуска Apache создавать 3 процесса
StartServers 3
# Apache не будет убивать свободные процессы, если их остается менее трех
MinSpareServers 3
# Максимум 5 свободных процессов, остальные будут уничтожаться
MaxSpareServers 5
О директиве MaxClients поговорим отдельно. Она устанавливает максимальное число параллельно обрабатываемых сервером запросов.
Рассчитать ее для OTRS можно следующим образом:

  1. При пиковой нагрузке (или нагрузочном тестировании) выполнить команду:
    ps -ylC /usr/sbin/apache2 | awk '{x += $8;y += 1} END {print "Average Proccess Size (MB): "x/((y-1)*1024)}'
    Где /usr/sbin/apache2 - имя процесса Apache в вашей системе (например apache2 или httpd).
  2. Команда отобразит средний объем процесса в мегабайтах (пример для OTRS Service Desk 6.0.5):
    Average Proccess Size (MB): 74.7298
  3. Значение MaxCliens не должно превышать значения по формуле:
    ((Общие объем оперативной памяти)(MB) - Прочие процессы (MB) / Средний объем процесса (MB)
  4. Таким образом, для сервера с общим объемом памяти в 15 ГБайт (за вычетом памяти прочих процессов) и средним объемом процесса в 75 Мбайт, MaxClients должен быть примерно 200. Если указать заниженное значение MaxClients, избыточные соединения будут ожидать в очереди. Если завысить - есть риск, что сервер начнет использовать своп, что приведет к существенному падению производительности.

Проверить, включено ли сжатие gzip (mod_deflate):
apachectl -t -D DUMP_MODULES | grep deflate

Тюнинг СУБД

PostgreSQL (в отличие от MySQL) поставляется с оптимальными настройками производительности.

Несмотря на это, для ряда специфических задач должен производиться избирательный тюнинг (в ряде случаев вместе с доработкой API OTRS).

Инструменты в помощь разработчику: perl Dprof, EXPLAIN и профилирование "тяжелых" запросов к базе.
Подробнее с тюнингом PostgreSQL можно ознакомиться тут.

Нагрузочное тестирование

Нам понадобится отдельный хост-клиент, который мы будем использовать для тестирования и утилита siege (последняя версия на момент написания заметки - 4.0.4). Тестирование необходимо проводить либо на наработанной базе OTRS (>1000 тикетов, в этом случае шаг 1 можно пропустить), либо наполнить базу командой ниже:

  1. На сервере приложений OTRS генерируем заявки с использованием OTRS Console:
    sudo -u otrs ./bin/otrs.Console.pl Dev::Tools::Database::RandomDataInsert \
    --generate-tickets 1000 \
    --articles-per-ticket 5
  2. В качестве нашего примера используется созданный в ходе написания предыдущей статьи экземпляр OTRS в Google Compute Engine
  3. На клиенте - с помощью curl -i или siege -g получить значение cookie (OTRSAgentInterface) для авторизации:
    curl -i "http://192.168.75.72/otrs/index.pl?Action=Login&RequestedURL=Action%3DAgentDashboard%3B&Lang=ru&TimeOffset=-240&User=test&Password=test"
    
    OTRS cookie
  4. На клиенте - подготовить файл urls.txt с перечнем ссылок для тестирования, пример:
    http://192.168.75.72/otrs/index.pl?Action=AgentDashboard
    http://192.168.75.72/otrs/index.pl?Action=AgentDashboard
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketQueue;QueueID=2;View=
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketQueue;Filter=Unlocked;View=Small;QueueID=1;
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketQueue;Filter=Unlocked;View=Medium;QueueID=3;
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketStatusView
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketStatusView;SortBy=Age;OrderBy=Down;View=;Filter=Closed
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketEscalationView
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketPhone
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketEmail
    http://192.168.75.72/otrs/index.pl?Action=AgentStats;Subaction=Overview
    http://192.168.75.72/otrs/index.pl?Action=AgentStats;Subaction=EditSpecification;StatID=new
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketSearch;Subaction=Search;TakeLastSearch=1;SaveProfile=1;Profile=good
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketSearch;Subaction=Search;TakeLastSearch=1;SaveProfile=1;Profile=raw
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=596
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=59
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=51
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=70
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=94
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=95
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=96
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=121
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=202
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=256
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=265
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=266
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=267
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=290
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketZoom;TicketID=341
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketOwner;TicketID=600
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketMerge;TicketID=600
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketPriority;TicketID=600
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketHistory;TicketID=600
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketPending;TicketID=600
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketPhoneInbound;TicketID=600
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketOwner;TicketID=548
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketMerge;TicketID=219
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketPriority;TicketID=592
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketHistory;TicketID=582
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketPending;TicketID=254
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketPhoneInbound;TicketID=412
    
  5. По желанию, профили тестирования можно сегментировать в разрезе задач, например, выделив полнотекстовый поиск:
    http://192.168.75.72/otrs/index.pl?Action=AgentTicketSearch&Subaction=Search&Fulltext=test&ResultForm=Normal&ShowAttributes=LabelFulltext&EmptySearch=1&ChallengeTocken=bQadwCSQgEP51LaK6wCkjPbrcN8Ba1HX
    
    или отбор конфигурационных единиц CMDB:
    http://192.168.75.72/otrs/index.pl?Action=AgentITSMConfigItem;SortBy=Number;OrderBy=Down;View=;Filter=141    
    
  6. Запуск тестирования (указать предварительно полученный cookie):
    sudo siege -t5M -H "Cookie: OTRSAgentInterface=P6Etsr84UqvXramvD3JXDWIWLam1llOx" -i -c 100 -f 
    
    В приведенном выше примере 100 конкурентных пользователей будут нагружать приложение запросами в течение 5 минут, последовательно (в режиме регрессионного тестирования) перебирая список URL. Для случайной выборки - запустить siege с ключом -i.
    Результат будет выведен следующим образом:
    Transactions:                  68284 hits
    Availability:                 100.00 %
    Elapsed time:                 299.70 secs
    Data transferred:            3039.35 MB
    Response time:                  0.41 secs
    Transaction rate:             227.84 trans/sec
    Throughput:                    10.14 MB/sec
    Concurrency:                   93.39
    Successful transactions:       68284
    Failed transactions:               0
    Longest transaction:            6.72
    Shortest transaction:           0.18
    
  7. Как альтернативу siege можно использовать стандартную утилиту ab (Apache Benchmark), к сожалению, неспособную работать со списком URL. Впрочем, в интернете попадаются и доработанные версии.

Интерпретация результатов

Transactions - число запросов к серверу за время тестирования
Availability - доступность сервера (% успешных соединений)
Elapsed time - продолжительность тестирования
Data transferred - объем данных, переданных сервером в ходе тестирования
Response time - среднее время отклика сервера
Transaction rate - производительность, среднее число запросов в секунду
Throughput - среднее количество данных, передаваемых в секунду
Concurrency - среднее число одновременных соединений
Successful transactions - число успешных соединений (код возврата HTTP < 400)
Failed transactions - число неуспешных соединений (код возврата HTTP 400 + socket timeout)
Longest transaction - продолжительность самой длинной транзакции
Shortest transaction - продолжительность самой короткой транзакции


Сравнение производительности mpm_prefork и mpm_event

Конфигурация тестового стенда
  • GCP Compute Engine n1-standard-4 (4 виртуальных ЦП, 15 ГБ памяти)
  • Debian 9.3 (4.9.0-5-amd64)
  • Apache 2.4.25
  • OTRS 6.0.5
  • GCP SQL PostgreSQL 9.6 (1 виртуальный ЦП, 3.75 ГБ памяти, 10 ГБ SSD)

Параметры тестирования
  • Продолжительность: 5 минут
  • Конкурентных пользователей: 100
  • Объем базы: ~1000 тикетов
  mpm_event (default) mpm_prefork
Transactions53033 hits68284 hits
Availability100.00 %100.00 %
Elapsed time299.48 secs299.70 secs
Data transferred2365.39 MB3039.35 MB
Response time0.54 secs0.41 secs
Transaction rate177.08 trans/sec227.84 trans/sec
Throughput7.90 MB/sec10.14 MB/sec
Concurrency94.8793.39
Successful transactions5303368284
Failed transactions00
Longest transaction5.946.72
Shortest transaction0.180.18

Источники

  1. mod_perl performance tuning
  2. Admin Manual: OTRS performance tuning
  3. Тюнинг веб-сервера Apache
  4. otrs.ru: нагрузочное тестирование OTRS 3.x (thnx Виктор Меркушев)
  5. Различия между prefork/worker/event
  6. PostgreSQL performance tuning