Планирование масштабных решений


SIP прокси перед сервером Asterisk (например: SER)


SER - это очень хороший маршрутизатор для SIP протокола, намного более сложный, чем Asterisk, поскольку он может просматривать содержимое пакетов и, на основе полученной информации, маршрутизировать вызовы или даже перезаписывает содержимое пакетов, основываясь на логике, специфичной для каждого пользователя.

Мы используем оба решения, SER и Asterisk, для очень масштабных решений. SER - это ЛУЧШИЙ SIP прокси сервер, который мне удалось найти. Но он является только sip прокси сервером. Он может обслуживать _МНОЖЕСТВО_ соединений (10,000 пользователей, 20 вызовов в секунду). Asterisk - это скорее телефонный коммутатор (АТС), реализующий множество функций, но, вследствие этого - более медленный.

Одна из приятных возможностей, присущей прокси серверу SER - это то, что пользователи могут устанавливать свои настройки для доступа по SIP, используя web интерфейс, без необходимости редактирования файлов конфигурации.

Q: В больших проектах (с множеством пользователей) - как Вы уменьшаете нагрузку на сервер Asterisk путем более эффективного управления RTP трафиком?
A: В данной ситуации нет однозначного решения, но вот мое мнение:

  • Если все Ваши абоненты находятся в пределах одной локальной сети, убедитесь, что Ваши SIP телефоны поддерживают возможность "re-invites" и используйте ее.
  • Если у Вас все пользователи подключаются через Internet, используйте SIP прокси сервер (по типу SER), в роли front-end'а в отношении сервера Asterisk. Вам по прежнему придется обрабатывать некоторое количество RTP потоков (по причине работы через NAT), но Вы можете распределить эту нагрузку с использованием нескольких SIP-прокси серверов в сети, при помощи записей SRV, технологии round-robin для DNS, или Вы можете заставить пользователей регистрироваться на различных прокси серверах.

Пример: FWD и SIPGATE - оба используют SER в паре с сервером Asterisk.

Было несколько пожеланий, где предлагалось сделать из Asterisk полноценный SIP прокси сервер. Если же Вы потратите некоторое время на изучение и понимание архитектуры Asterisk, то Вы поймете, что это все равно не работало бы. Я не говорю, что обработка SIP каналов не может быть улучшена, я только хотел сказать, что все это должно работать еще и с остальной архитектурой, заложенной в сервере Asterisk. Сервер Asterisk в комбинации с отдельным SIP прокси сервером - является очень мощным решением.

При использовании SIP прокси сервера, у нас имеется следующий сценарий:


  • UA клиент Alice отправляет сообщение INVITE для bob@domain
  • Прокси сервер, отвечающий за данный домен, принимает это сообщение и ищет абонента "bob" в таблице размещения пользователей или таблице псевдонимов пользователей.
  • Прокси сервер ПЕРЕСЫЛАЕТ тот же самый запрос INVITE к bob@currentlocation, или, может быть, в несколько мест.
  • Когда Bob с какого то места, куда пришел вызов, отвечает на него, прокси отменяет вызов в те места, откуда не последовало ответа и перенаправляет сообщение OK абоненту Alice.
  • Абонент Alice сообщением ACK, отправляемого пользователю bob, подтверждает OK и соединение установлено.

В данном сценарии, представлен только диалог по протоколу SIP, между пользователями Alice и Bob, с сервером, находящийся на пути прохождения сигнализации, и работающего в роли прокси сервера, а не пользовательского агента (UA) (прокси сервер не может и не должен отвечать или быть инициатором вызовов).

Цитата


Мы используем SER в связке с Asterisk. SER используется в качестве SIP proxy/registrar, Asterisk - в роли SIP - PSTN шлюза и сервера для голосовой почты, конференций и перевода вызовов.

Преимущества: Масштабируемость, может поддерживаться очень большое количество SIP клиентов с помощью простого доступа к интерфейсу управления пользователями на основе сервера базы данных или RADIUS, расширенные возможности логики и маршрутизации для SIP протокола, лучшая совместимость с другими компонентами SIP сети.
Неудобства: Вам необходимо два сервера, SER не работает с IAX и, как следствие, вся обработка IAX пользователей осуществляется сервером asterisk.

В моем решении, Asterisk общается с SIP клиентами (UA) через SER - это удалось сделать, установив маршрутизационную запись для логики маршрутизации сервера SER. Я так же пропускаю RTP поток через SER - это было сделано с помощью модуля "rtpproxy" (SER).

По моему мнению, если Вы планируете использовать большое число SIP клиентов - то это довольно неплохая идея.
-Dawid Mielnik-


Диаграмма работы Asterisk с SER

Очень хорошая диаграмма, демонстрирующая работу SER совместно с Asterisk.


MWI - message waiting indication (Индикатор наличия новых голосовых сообщений)

Метод 1

Я не использую Asterisk в качестве клиента (UA), SIP пользователи не регистрируются на Asterisk, вместо этого, все это обрабатывается на SER. Итак, серверу Asterisk необходимо знать, как ему добраться до телефона. Для этого Вам необходимо описать секции "peer" для каждого телефона в файле sip.conf (Которые могут быть созданы на основании регистрационных данных сервера SER, с использованием приложений ast_data / res_data, или механизмом "realtime"). Заметьте, что эти записи никогда не будут использованы для исходящих вызовов, а используются только для обеспечения нормальной работы индикатора MWI.

Итак, нам необходимо найти такой путь, чтобы сервер Asterisk мог общаться напрямую с телефонами, когда для какого-то из них имеются новые голосовые сообщения - индикатор MWI (host=). Один из возможных путей получения этого IP адреса - это использование динамических записей DNS: DDNS.

В любом случае, Вам необходимо создать запись типа "peer", для каждого телефона, примерно такую:

[2114]
type=peer
username=2114
insecure=yes
canreinvite=no
context=default
mailbox=2114
host=SIP003094C274B3.bna01.isdn.net

Метод 2 - от Andreas Granig

Q: Я предполагаю, что asterisk может отправлять SIP сообщения NOTIFY зарегистрированным SIP клиентам через сервер SER. Итак, могу ли я создать специальный модуль для серверов Asterisk и SER, для того, чтобы это работало?
A: Сервер Asterisk отправляет сообщения NOTIFY только для клиентов (UAC), которые зарегистрированы на Asterisk. Если Вы отправляете все вызовы на голосовые ящики в Asterisk и при этом Ваши клиенты (UAC) регистрируются на сервере SER, Вы можете использовать параметр 'externnotify' в файле voicemail.conf сервера Asterisk. Мы используем скрипт, который работает с sipsak, для включения и выключения индикатора MWI, отправляя соответствующие сообщения NOTIFY.

Более детальная информация от Paul (Java Rockx): Я использую sipsak, для отправки сообщений с моего сервера Asterisk в SER прокси. Я использую в Asterisk параметр: "externnotify" в файле voicemail.conf, где указываю имя внешнего bash скрипта. Этот скрипт просто создает файл "touch" в директории /var/spool/mwi/, для дальнейшей обработки его через cron.

Задача, запущенная из cron, просматривает и считывает все файлы в директории /var/spool/mwi/ и генерирует соответствующие SIP NOTIFY сообщения, использую sipsak для передачи их в ser прокси сервер. Заметьте, что сервер asterisk - зарегистрирован как клиент (UA) на прокси сервере Ser. Проделывая это, я предполагал, что можно просто использовать вызов sipsak из сервера asterisk, для отправки сообщений NOTIFY в сервер Ser.

У меня это прекрасно работает, когда нужно включить индикатор MWI у клиента (UA). То, что все еще Я не могу сделать - это выключить индикатор MWI, когда нет новых сообщений. Я реально потратил куче времени для того, чтобы понять, как обработать событие "Hang-Up" в Asterisk. По существу, мне нужно иметь "externnotify" для обработки события отсоединения пользователя от его голосового ящика, тогда Я мог бы проверить статус сообщений в голосовом ящике и отменить работу индикатора MWI, если в ящике более нет новых сообщений.

Я также хочу обрабатывать сообщения SUBSCRIBE, которые получает SIP прокси сервер. Я планирую использовать файл ser.cfg для выполнения внешнего скрипта, при приеме сообщения, для дальнейшей переправки его в Asterisk, при помощи задачи в cron. Когда сервер Asterisk получает сообщение SUBSCRIBE, то он обрабатывает его также, как если бы пользователь вышел из голосовой почты и было бы запущено событие, определенное в "externnotify".

...а тут можно найти решение!

Метод 3

Q: Если у Вас имеются [SIP] телефоны, которые регистрируются на прокси сервере [SER], но голосовые ящики обрабатываются сервером asterisk, то, как включить [MWI] (Индикатор наличия голосовых сообщений) на телефонах?

A: В файле sip.conf создайте запись для вашего маршрутизатора [SER].

[ser]
type=friend ; Позволяем входящие и исходящие вызовы.
; используйте "peer", если нужно только управлять индикатором MWI
context=ser ; Контекст для входящих вызовов.
host=ser.server.tld ; имя хоста или IP адрес Вашего SER сервера
fromdomain=ser.server.rld ; Это Ваш SER_DOMAIN
insecure=very ; Этим мы разрешаем входящие вызовы с телефонов,
; которые попадают через ser в наш asterisk
mailbox=user@context ; Это список голосовых ящиков для мониторинга

Это задает серверу asterisk то, что если есть новая голосовая почта для пользователя "user", тогда ему необходимо отправить сообщение SIP NOTIFY на телефон "ser.server.tld". Итак, пока все хорошо, кроме того, как будет SER доставлять это сообщение заданному телефону? Простейший путь, это сделать малюсенькое изменение в исходном коде asterisk, для того, чтобы добавить имя пользователя голосового ящика в SIP сообщение NOTIFY.

--- channels/chan_sip.c.orig    Thu Jul 14 12:03:18 2005
+++ channels/chan_sip.c Thu Jul 14 12:05:26 2005
@@ -9710,6 +9710,7 @@
        /* Called with peerl lock, but releases it */
        struct sip_pvt *p;
        int newmsgs, oldmsgs;
+       char *s;

        /* Check for messages */
        ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs);
@@ -9735,6 +9736,10 @@
        /* Recalculate our side, and recalculate Call ID */
        if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
                memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
+       strcpy(p -> username, peer -> mailbox);  /* Username = Mailbox name */
+       s = strchr(p -> username, '@');          /* Remove the context part */
+       if (s != NULL)
+                *s = 0;
        build_via(p, p->via, sizeof(p->via));
        build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
        /* Send MWI */


После применения этого патча, сообщения NOTIFY для MWI поступают с сервера asterisk с установленном полем URI: . И далее, оно уже будет отправлено прокси сервером Ser на нужный телефон, с использованием нормальной таблицы правил маршрутизации [SER]. Т.е., [SER] делает поиск: lookup("location"), а потом: t_relay(). Я не надеюсь, что этот патч приведет к побочным эффектам на телефонах, которые управляются не сервером ser.

Для меня, этот метод более прост, чем Метод 2, описанный выше. Вы можете добавить столько голосовых ящиков в параметр "mailbox=", файла конфигурации asterisk sip.conf, сколько Вам необходимо. Одна из возможных проблем - это, если у Вас имеются голосовые ящики с названием "1000@cx1", а другой: "1000@cx2", в результате, данный патч будет включать индикатор MWI для телефона "1000@ser.server.tld" когда есть новые сообщения в одном из этих двух ящиков. Небольшая модификация для этого патча, и сервер SER сможет обрабатывать различные контексты для голосовых ящиков, если есть в этом необходимость. Однако, тот простой вариант, который есть, для меня вполне достаточен.

Метод 4 - использование механизма "realtime" (ARA) и загрузка всех SIP клиентов при запуске Asterisk

Q: Мы используем в Asterisk архитектуру Realtime для голосовых ящиков и для SIP клиентов. Таблицы базы данных с SIP клиентами видна для таблицы subscriber в OpenSER.
Индикатор MWI для пользователей работает только в том случае, если пользовательская запись (sip клиент) загружается в память и видна, при помощи CLI команды "sip show peers". Это случается, например, если пользователь совершает вызов на свой ящик для проверки голосовой почты.
Имеется ли возможность загрузить всех клиентов из базы данных при запуске asterisk, тем самым, давая возможность пользователям получать сообщение NOTIFY, не требуя то пользователей предварительно совершать вызов на свой голосовой ящик?

A: Смотрите эту ссылку: http://article.gmane.org/gmane.comp.telephony.pbx.asterisk.user/134846

Примеры конфигурации

Работа связки Asterisk и SER:
1. Укажите различные порты для приема сообщений по протоколу SIP для SER (/etc/ser/ser.cfg) и Asterisk (/etc/asterisk/sip.conf).
2. Сконфигурируйте прокси сервер SER (/etc/ser/ser.cfg) на переадресацию вызовов на основании пункта назначения вызова. Например, добавив:

if (uri=~"^sip:0[0-9]*@yourdomain") {
forward( 10.10.10.10, 5070 ); //IP адрес и порт, который слушает asterisk
break;
}

Сервер Asterisk и SER на одной машине


>Если для Asterisk указан SIP порт - 5061, а для прокси сервера SER
>он остается равным 5060, тогда как сделать, чтобы Asterisk общался
>с SER и наоборот?

Можно сделать что-нибудь типа этого:
В файле Asterisk, extensions.conf:

[globals]
SERADDRESS=XXX.XXX.XXX.XXX:5060

[context]
exten => ,1,Dial(SIP/${EXTEN}@${SERADDRESS},20,r)

В файле ser.cfg:

if (method == "INVITE") {
if (uri =~ "sip:1[0-9]{10}@*"){
log(1, "Forwarding to Asterisk\n");
rewritehostport("XXX.XXX.XXX.XXX:5061");
t_relay();
break;
}
}

(Документация в SER admin guide: http://www.iptel.org/ser/doc/seruser/seruser.html)



Вводная информация, о различиях между сервером Asterisk и SER

от Alex Barnes

Многие говорят, что Asterisk позволяет достичь большей масштабируемости
для SIP протокола. Например, можно взвалить на Ваш SIP прокси все, связанное
с обработкой задач, таких как: передача повторных запросов/ перенаправления /
поиск зарегистрированных абонентов / протоколы вызовов / и т.д.,
все из которых могут быть скрыты от Asterisk.

Множественные регистрации клиентов:
Asterisk не поддерживает несколько регистраций одного клиента.
Прокси сервер регистраций (registrar proxy) может поддерживать
данную возможность, позволяя использовать возможность разветвления
вызовов к данному клиенту (последовательные вызовы, параллельные
или комбинация этих случаев).

Grey Areas (Функциональность, которая содержиться в Asterisk, так и в Прокси серверах)
CPL:
Ценность любого прокси сервера, заключается в наличии у него встроенного
механизма CPL, который позволяет создавать хорошие скрипты для обработки
входящих или исходящих вызовов, индивидуально для каждого из пользователей.

Сервера приложений:
Прокси может также быть и сервером приложений. Который может быть
использован для доступа к некоторым дополнительным технологиям.
Например, Ubiquity сделал HA SIP Сервер приложений, который может
делать почти все что угодно, при помощи загрузки соответствующего RMI
для клиентских и серверных приложений, SOAP, связь с Web Application Servers (Websphere /
Weblogic), Java Eventlets, который дает возможность Вам самим написать
свой интерфейс с использованием других SIP SDK, для обработки вызовов.

ТЕМ НЕ МЕНЕЕ
Я не думаю, что сервер Asterisk полностью готов к поддержке
всех, реально существующих, сценариев доставки вызовов, которые
включены в реализации SIP прокси сервера сторонних разработчиков.
Одна из проблем, с которой я столкнулся в Asterisk, это то, что он
не обрабатывает зацикливание звонка обратно на себя.

Например, поступает вызов через PSTN в Asterisk, он переправляет его
на Ваш SIP registrar proxy, который ищет запись, соответствующую
полученному SIP адресу и находит, что пользователь зарегистрирован
на аналоговом телефоне. Если SIP сервер регистраций перенаправит
вызов с использованием ответа: " 3xx", тогда Asterisk дальше успешно
продолжит обработку, однако, если прокси сервер хочет остаться
на пути прохождения вызова (может быть у Вас на нем работает
приложения для билинга), то он добавит заголовок "Record-Route"
в SIP запрос, дабы сообщить, что он желает получать все последующие
сообщения, связанные с этим вызовом, и отправит его обратно к Asterisk.
В этом случае, Asterisk будет всегда игнорировать это сообщение INVITE.
Если же пользователь был бы зарегистрирован на надлежащем SIP узле,
тогда петля не получилась и все сработало бы как надо.



Пример: SER, Asterisk и Lucent TNT

от Michael Shuler
Вы можете сделать то-же, что и мы, настроив два SER сервера, которые балансируют нагрузку от Foundry ServerIron XL (Вы можете использовать бесплатный UltraMonkey, если желаете). Эти две машины с 2 SER обрабатывают сообщения REGISTER, содержат NAT сервер и осуществляют окончательную доставку вызовов к VoIP устройствам и к телефонным шлюзам. Машины с серверами SER не знают, что делать с вызовами, а знают только, что их надо передать серверу Asterisk для дальнейшей классификации и маршрутизации или для всех действий, которые Вы хотите сделать с этими вызовами. У Вас может быть несколько серверов с Asterisk, которые являются только шлюзами или транскодерами голосовых кодеков для медиаданных, имея набор карт PRI на борту. Мы не использовали сервер Asterisk в качестве шлюза медиаданных в своей системе. Мы использовали Lucent TNT, которые использовались в тех же целях, но в больших масштабах. Для совместного использования общих конфигурационных данных мы использовали http://svn.asteriskdocs.org/res_data/, для чтения содержимого всех фалов конфигурации(sip.conf, extensions.conf, и т.д.) в реальном времени из базы данных MySQL. Просто немного пропатчили и все.

Пока мы не обнаружили приделов по расширяемости этой системы. Если нагрузка на эти два SER сервера достигнет предела, мы просто добавим еще один. Если же будет перегружен сервер маршрутизации Asterisk, то мы добавим еще один. Если же у нас кончаться каналы PRI, тогда мы добавим еще один TNT и больше PRI интерфейсов в нашем Plexus 9000. Таким образом, теоретически, данная система не имеет пределов расширяемости, для решения поставленных задач.

Тут можно найти простые примеры конфигурации SER.

Пример: TeleSIP

Q: Знаете ли Вы о какой-либо документации, по вопросу конфигурации SER в роли внешнего интерфейса (front-end) для Asterisk?

A: В TeleSIP мы запустили кластер из нескольких географически распределенных SER серверов, которые обрабатывают всю маршрутизацию SIP протокола. Прокси сервер SER - это грамотная, быстрая и стабильная платформа, которая у нас работала безупречно. Мы использовали Asterisk как внутреннюю АТС компании и шлюз в телефонную сеть общего пользования. В основном, Вам нужно разработать план нумерации так, чтобы логика маршрутизации SER серверов могла переправить вызов к Asterisk, когда это необходимо.

R: Другой пример можно найти в руководстве IPtel.org. Пример показывает, как использовать прокси сервер SER в роли внешнего интерфейса (front-end) к шлюзу Cisco в общую телефонную сеть, но также показывает, как использовать SER в роле внешнего интерфейса (front-end) к Asterisk.

Ссылки по теме: