Тестирование нагрузки на Астериск сервер при помощи sipp

Администратор,

asterisk
Данная статья описывает, как протестировать нагрузку на Asterisk сервер путем эмуляции звонков при помощи утилиты sipp. Имеются следующие исходные данные:

Два сервера с адресами 192.168.0.1 и 192.168.0.2. Звонки эмулируются утилитой sipp с сервера 192.168.0.1 на Asterisk сервер 192.168.0.2.
В Asterisk сервер 192.168.0.2 установлена карта Digium TE207P и настроен SS7 (ОКС7) линк с провайдером локальной связи. 
Звонки с сервера sipp по SIP протоколу поступают на сервер Asterisk и далее направляются через ОКС7 линк на многоканальный номер с интерактивной системой голосовой почты. Сценарий тестирования sipp должен набрать через DTMF тоны пароль на голосовой ящик и завершить звонок.

SIPP


Утилита sipp представляет собой открытый инструмент по тестированию и генерации трафика для SIP протокола. Преимуществом данного инструмента являеется поддержка TLS, SIP аутентификации, условных сценариев, UDP ретрансмиссий, регулярных выражений, возможности вставки произвольных заголовков, логирование, выполнение системных команд в зависимости от результата (в скриптах автоматизации и мониторинга, например). Одной из самых впечатляющих возможностей является поддержка посылки RTP трафика через RTP echo (прием и отправка обратно полученного), а также RTP replay 
- Подробная информация о sipp находится на домашней странице проекта.

Установка в Gentoo


Для Gentoo это делается весьма просто

explorer tmp # echo net-misc/sipp pcap >> /etc/portage/package.use
explorer tmp # echo net-misc/sipp ~x86 >> /etc/portage/package.keywords
explorer tmp # emerge -av sipp

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild  N    ] net-libs/libnet-1.1.2.1-r1  USE="-doc" 998 kB
[ebuild  N    ] net-misc/sipp-1.1_rc8  USE="pcap ssl -debug" 168 kB [2]

Total: 2 packages (2 new), Size of downloads: 1,166 kB
Portage overlays:
 [1] /usr/portage/local/layman/rox
 [2] /usr/portage/local/layman/voip

Would you like to merge these packages? [Yes/No] Yes
Отвечаем Yes и система сама скачает нужные пакеты и установит их.

Установка из исходных кодов


Скачать sipp
Распаковать
make ossl && make install (либо просто make && make install если не нужна поддержка SIP аутентификации)
Примечание: для сборки sipp необходима библиотека ncurses-devel. Также нужна openssl-devel для авторизации с паролем.

Настройка Asterisk


sip.conf
Для того, чтобы принять звонок от sipp в Астериск должен быть настроен соответствующий peer.

[sipp]
host=192.168.0.1
type=friend
context=sipp
canreinvite=no
disallow=all
allow=ulaw
extentions.ael

Настаиваем тестовый план набора

context sipp {
        _X. => {
                Answer;
                Wait(3);
                Hangup;
        }
}

Пробный запуск


Проверяем настройки пробным запуском

sipp -sn uac 192.168.0.2 -s 100 -d 100000 -l 1 -i 192.168.0.1
что значит набрать номер 100 на SIP сервере по адресу 192.168.0.2, используя локальный адрес 192.168.0.1  в поле From: (в случае нескольких сетевых карт); использовать сценарий uac, одновременно поддреживать один сеанс связи (l) длиной 10 секунд (d).

Сценарий uac представлен ниже:

SIPp UAC            Remote
    |(1) INVITE         |
    |------------------>|
    |(2) 100 (optional) |
    |<------------------|
    |(3) 180 (optional) |
    |<------------------|
    |(4) 200            |
    |<------------------|
    |(5) ACK            |
    |------------------>|
    |                   |
    |(6) PAUSE          |
    |                   |
    |(7) BYE            |
    |------------------>|
    |(8) 200            |
    |<------------------|
В CLI Asterisk видим следующие строки

    -- Executing [100@sipp:1] Answer("SIP/sipp-008b2010", "") in new stack
    -- Executing [100@sipp:2] Wait("SIP/sipp-008b2010", "3") in new stack
    -- Executing [100@sipp:3] Hangup("SIP/sipp-008b2010", "") in new stack
  == Spawn extension (sipp, 100, 3) exited non-zero on 'SIP/sipp-008b2010'
Если не видим, включаем sip debug и выясняем почему.

Включаем эхо-тест


Приведенный ваше тест не включает работы с RTP, поэтому не является достоверным. Как уже было сказано выше, sipp имеет возможность отсылки обратно полученного RTP трафика, по образу и подобию стандратной астерисковой команды Echo.

Модифицируем план набора

context sipp {
        _X. => {
                Answer;
                Wait(0.5);
                Playback(demo-tanks);
                Hangup;
        }
}
И выполним

sipp -rtp_echo -mi 192.168.0.1 -sn uac 192.168.0.2 -d 2000 -s 100 -rp 2000 -r 5 -i 192.168.0.1 -l 1 .
Проверить, на самом деле ли происходит отсылка обратно можно снифером

tcpdump -n host 192.168.0.2
04:39:18.145805 IP 192.168.0.1.5060 > 192.168.0.2.5060: SIP, length: 357
04:39:18.145952 IP 192.168.0.2.5060 > 192.168.0.1.5060: SIP, length: 422
04:39:18.545874 IP 192.168.0.1.5060 > 192.168.0.2.5060: SIP, length: 515
04:39:18.546135 IP 192.168.0.2.5060 > 192.168.0.1.5060: SIP, length: 414
04:39:18.546381 IP 192.168.0.2.5060 > 192.168.0.1.5060: SIP, length: 640
04:39:18.546434 IP 192.168.0.1.5060 > 192.168.0.2.5060: SIP, length: 357
04:39:19.047004 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172
04:39:19.047087 IP 192.168.0.1.6000 > 192.168.0.2.18904: UDP, length 172
04:39:19.066390 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172
04:39:19.066415 IP 192.168.0.1.6000 > 192.168.0.2.18904: UDP, length 172
04:39:19.086380 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172
04:39:19.086403 IP 192.168.0.1.6000 > 192.168.0.2.18904: UDP, length 172
04:39:19.106374 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172
04:39:19.106397 IP 192.168.0.1.6000 > 192.168.0.2.18904: UDP, length 172
04:39:19.126372 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172
04:39:19.126395 IP 192.168.0.1.6000 > 192.168.0.2.18904: UDP, length 172
04:39:19.146368 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172
04:39:19.146391 IP 192.168.0.1.6000 > 192.168.0.2.18904: UDP, length 172
04:39:19.166365 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172
04:39:19.166393 IP 192.168.0.1.6000 > 192.168.0.2.18904: UDP, length 172
04:39:19.186401 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172
04:39:19.186425 IP 192.168.0.1.6000 > 192.168.0.2.18904: UDP, length 172
04:39:19.206397 IP 192.168.0.2.18904 > 192.168.0.1.6000: UDP, length 172

Как видим, RTP пакеты отсылаются в обе стороны. Если этого не происходит, то первым делом надо смотреть настройки firewall.

Тестирование ОКС7 линка


В нашем сценарии звонок с сервера 192.168.0.1 (sipp) поступает на сервер 192.168.0.2 (asterisk) и далее по ОКС7 линку направляется провайдеру на терминацию. Для этого используется следующий план набора:

context sipp {
        _X. => {
                Set(CALLERID(num)=91802123);
                Dial(SS7/918602000);
                Hangup;
        }
}
Как видим, ничего сложного.

sipp запускался со следующими параметрами:

sipp -rtp_echo -mi 192.168.0.1 -sn uac 192.168.0.2 -d 200000 -s 100 -i 192.168.0.1 -l 60)
Оценка качества и предельной загрузки
Для оценки качества связи можно позвонить с IP телефона через Asterisk в момент пиковой нагрузки. Также необходимо проанализировать вследующие параметры:

Загрузка CPU (команда top). Именно CPU опеределить верхний предел возможностей сервера.
Проблемы с прерываниями. Утилита zttool покажет, наблюдается ли нехватка прерываний (IRQ misses).
Можно пропустить звонок через команду Monitor и прослушать записанный файл. Если предельная нагрузка достигнута, это будет видно по записи.
Логи астериска. Обычно когда система работает на пределе появляются ошибки. Например, если заранее не увеличить число файловых дескрипторов (ulimit -n), то на рубеже сотни звонков значения по умолчанию (1024) не хватит. Чтобы увидеть, сколько открытых файлов держит астериск, нужно выполнить команду
lsof -p {{ps uax grep asterisk grep -v grep awk '{print $2}'}} wc -l
Результаты тестирования
За 13 часов работы было пропущено 496,361 звонков с 60-тью звонками в пике. Проблем со стабильностью Asterisk системы не наблюдалось. Однако были выявлены проблемы с нехваткой ресурсов и некорректной конфигурацией ядра:

[Sep 19 18:06:38] WARNING[22638] l4isup.c: Limit exceeded when trying to adjust numbufs to 8, for circuit 49.
[Sep 19 18:06:38] NOTICE[22638] l4isup.c: Write buffer full on CIC=49 (wrote only 0 of 160), audio lost.
[Sep 19 18:06:38] WARNING[22638] l4isup.c: Limit exceeded when trying to adjust numbufs to 8, for circuit 49.
[Sep 19 18:06:38] NOTICE[22638] l4isup.c: Write buffer full on CIC=49 (wrote only 0 of 160), audio lost.
Так как непосредственно к организации тестирования это не относится, это описано в документе по настройке ОКС7 в Астериск.

Воспроизведение записанного RTP трафика (replay)
sipp позволяет воспроизвести записанный при помощи tcpdump или wireshark RTP поток. Будет описано когда подойдем к тестированию IVR при помощи DTMF.

little howto
Проблемы
Ошибки сборки
sipp ругается на 2007-09-19 02:16:09: [OpenSSL] is required for the -ap option..

Не слинковалась библиотека openssl. Установить openssl-devel, проверить флаг -I в Makefile, чтобы искал заголовочные файлы в правильном месте. Почему-то у меня искал в /opt/openssl/include: INCDIR_linux=-I. -I/opt/openssl/include. Заменить на INCDIR_linux=-I. -I/usr/include/openssl

Не собирается make ossl
Возможные варинты:

Нет include файлов. Ошибка на уровне компиляции.
Не находит библиотеку 
- ошибка на уровне линковщика. Пример
Unknown macro: {/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/bin/ld}
Указать путь к библиотеке при помощи -L директивы либо создать символическую ссылку (например, ln -s /usr/lib64/libssl.so.0.9.8 /usr/lib64/libssl.so). Правильно слинкованный с openssl бинарник выглядит так:
Unknown macro: {max@srv}

Ошибки работы Asterisk


Проблемы, выявленные в процессе тестирования, описаны в SS7. Это проблемы, связанные с нехваткой рерурсов CPU, буферов, и другие.