gifts2017

ROM-Asterisk в высоконагруженных проектах интеграции

Опубликовал Олег Ризванов (oleg.rizvanov) в раздел Оборудование - Телефония, SIP

Хочу поделиться опытом, нажитым непосильным трудом при реализации больших проектов по интеграции 1С и Asterisk.
ROM-Asterisk неплохо себя проявил под большими нагрузками. Выделю основные рекомендации, которые следует выполнять при интеграции с высоконагруженными Asterisk

Тонкая настройка фильтров на основе регулярных выражений

Фильтрация на базе регулярных выражений - это мощный инструмент внешней компоненты ROM-Asterisk. В других внешних компонентах для работы с Asterisk эта функциональность отсутствует.

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

Правильная настройка фильтра регулярных выражений дает возможность "отбить" лишние события еще на стороне ROM-Asterisk, не пуская их в процедуру ОбработкаВнешнегоСобытия и тем самым значительно снять нагрузку с пользовательского сеанса 1С.

В идеале, сеанс пользователя 1С должен получать только те события Asterisk, которые касаются только его.

Пример

Пользователь Василий имеет внутренний номер телефона "902".
При начале входящего звонка, еще до поднятия трубки, необходимо показать номер звонящего.  А при ответе на звонок, необходимо создать документ "Событие".

Соответственно, пользовательский сеанс 1С должен отслеживать события Asterisk: Dial, Bridge и Hangup. Но, не все, а только касающиеся номера "902".

Событие Dial выглядит следующим образом:

Event: Dial 
Privilege: call,all
SubEvent: Begin
Channel: SIP/202-0000019c
Destination: SIP/902-0000019d
CallerIDNum: 202
CallerIDName: Operator-202
ConnectedLineNum: 902
ConnectedLineName: Vasiliy-902
UniqueID: 1335616897.790
DestUniqueID: 1335616897.791 Dialstring: 902

 

Для этого применим регулярное выражение:

Dial.{1,}?902|Bridge.{1,}?902|Hangup.{1,}?902

 

Можно слегка усложнить задачу, ведь нам важно получать только события начала звонка, т.е. Dial...Begin, а в при использовании фильтра выше, в сеанс Василия попадут еще и события окончания набора Dial...End. Модифицируем регулярное выражение:

Dial.{1,}?Begin.{1,}?902|Bridge.{1,}?902|Hangup.{1,}?902

 

Установка строки фильтра выполняется с помощью метода УстановитьРегулярноеВыражение объекта ROM-Asterisk.

Правильная настройка фильтров классов событий Asterisk

Еще одним способом уменьшить количество событий, обрабатываемых сеансом 1С, является установка фильтра классов событий Asterisk.

Например, если в сеансе пользователя 1С нужно получать только события о звонках, тогда имеет смысл ограничить этот сеанс только классом "call". Сделаем это с помощью команды Events:

Action: Events Eventmask: call

Отправка команды серверу Asterisk выполняется с помощью метода ВыполнитьКоманду объекта ROM-Asterisk.

Обязательное закрытие клиентского соединения с Asterisk

ROM-Asterisk дает возможность клиентскому сеансу 1С открывать более одного соединения. Поэтому, при закрытии сеанса следует выполнить команду Logoff, чтобы не оставлять Asterisk Manager "висящих" коннекций.

Action: Logoff

Отправка команды серверу Asterisk выполняется с помощью метода ВыполнитьКоманду объекта ROM-Asterisk.

Использование проксирования при большом количестве клиентов

При большом количестве клиентских соединений Asterisk Manager может начать обрывать соединения. Опытным путем установлено, что данная проблема возникает при использовании более 50-ти соединений.

Для решения этой проблемы, можно использовать так называемые AMI-proxy. Принцип их работы в том, что все клиентские сессии они держат на себе, а к Asterisk Manager-у имеется только одна коннекция. Достаточно хорошо себя зарекомендовал AstManProxy. Проект открытый и неплохо документирован.

Коллеги из МИКО написали в блоге статью по установке AstManProxy

Заключение

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

Оптимизируйтесь Cool

Ссылки

ROM-Asterisk: свободная внешняя компонента для связи 1С и Asterisk

AstManProxy: open-source proxy для Asterisk Manager

См. также

Подписаться Добавить вознаграждение

Комментарии

1. krein (krein) 14.01.13 23:39
Я так понял, что компонента ROM-Asterisk не дает переводить звонок,
это означает, что его вообще не перевести,
или просто придется это делать из софтфона и "событие" не скорректируется в 1с?
2. Олег Ризванов (oleg.rizvanov) 15.01.13 01:04
(1) krein,
Перевод делается очень легко и просто.
Есть 2 вида перевода: условный и безусловный
Условный выполняется командой: Atxfer
Безусловный выполняется командой: Transfer
Эти команды нужно отправить на сервер методом компоненты ROM-Asterisk - ВыполнитьКоманду()
Так что, все у вас получится :-)
3. Станислав Патырило (wondermaker) 13.06.13 05:04
Прокси для АТС? Все сидят и "слушают"?
А может проще можно сделать? Зачем всем сидеть "в консоли", покдлюченными к АТС, если можно устроить игру "царь горы", когда этим занимается 3-5 пользователей, динамически отслеживающих наличие входящих вызовов и пишут это в регистр. А уже прочие пользователи просто получают информацию из регистра и "понимают", что звонок касается их номера.
Если один из "слушателей" отвалился (нет данных о том, что он следит за АТС крайние 2-3-5 секунд - следим через РегСвед), то новый становится на его место и следит и пишет события телефонии в регистр. Основные проблемы - это определение "царей" и исключение дублей в регистре при записи несколькими слушателями.
Оригинацию звонков делают все подключенные клиенты своими компонентами - там нагрузка не велика.
В итоге, при 3-5 слушателях будет еще 2-3 одновременных подключения (не знаю сколько нужно осуществлять звонков, чтобы каждую секунду было больше вызовов).

Пока у нас нагрузка небольшая и пропущенных вызовов не замечено, но это явно лучше, чем мучать АТС прокси.

P.S. пояснение: компонента работает только на клиенте, посему сделать одно подключение с севера без клиентов не получается.
4. Олег Ризванов (oleg.rizvanov) 13.06.13 11:31
(3) wondermaker,

ИМХО, не взлетит...

1) Допустим у нас 100 одновременных звонков в минуту (для колл-центра, это нормально). По каждому звонку нам нужно как минимум 3-4 события. Обязательные: начало звонка, соединение с абонентом, завершение звонка. Опционально: файл записи. В итоге, в регистр сведений, который вы предлагаете, будет попадать 300-400 записей в минуту. Соответственно, за день - 144 000 записей, а за 7 дней их будет уже миллион (точнее 1008000).

2) Представьте нагрузку на сервер БД и на сервер приложений 1С... Кроме того, что сервер будет записывать большое количество записей, так еще каждые 2-3-5 секунд, как вы предлагаете, его будет дергать 1С-клиенты, чтобы спросить "а нет ли для меня событий в регистре сведений?".
Вам ресурсов хватит? Ведь пользователи еще должны работать, например, Расходные проводить...

И последнее... Насчет вашего P.S.-а
компонента работает только на клиенте, посему сделать одно подключение с севера без клиентов не получается

А какой в этом смысл?
Допустим, у вас есть волшебная ВК, которая работает на сервере (это сделать не сложно) и вы даже написали серверную функцию, которая слушает Asterisk. И что дальше? Кто вызовет эту серверную функцию? Она сама вызовется или все-таки нужен клиент?
А если, все равно нужен клиент, то напрашивается вопрос: "А зачем тогда сервер, если все можно сделать на клиенте???"

P.S.
Вы хороший спецалист, просто не до конца разобрались в проблеме :)
5. Станислав Патырило (wondermaker) 14.06.13 04:11
Количество записей не критично, т.к. в данном регистре хранить все записи нет смысла - они чисто для обработки в текущем режиме и можно очищать периодически.

А тут мы и решаем какие события ловим - нужно ли нам знать кто на линию попал?
Если используется очередь, то какой смысл знать, что кто-то есть в очереди? Ловим только событие поднятия трубки и пишем данные в регистр. Задержка в появлении мастера создания нового события (а там еще поиск номера телефона по базе в 300 тыс. строк) составляет в рабочем режиме 1-2 секунды (т.е. оператор/менеджер еще не успел сказать "драсьте", а окно уже показывает кто на линии. Максимум задержки поймали в 5 секунд при первом запуске на тестовом сервере.

У нас на одном сервере работает несколько баз с общим количеством одновременно работающих пользователей порядка 160-170 и обрабатываемые объемы информации не малы. А база, к которой прикрутили ASterisk крутится на другом более мощном сервере с минимальной нагрузкой.

В одной конфигурации видел схему, когда внешний сервис мониторит Asterisk и передает данные на web-сервис в 1С. Минусы за полгода выловили такие
1) при не очень большой нагрузке (порядка 20-30 звонков в минуту) были пропущенные звонки - тоочнее из-за задержки обработки попадали в базу через 5-10 секунд. Фильтры не достаточно гибкие
2) схема работы внешней программы не оптимальна - подклчюение к web-сервису происходил по 12-13 раз в секунду, что, подозреваю, и приводит к потерям и задержкам
3) периодически софт подвисает и звонки не поступают в базу.

С нашей схемой такого не наблюдается, хотя нагрузка выше.

Нагрузки в 100 звонков в минуту у нас, пока, не предвидится, хотя, было бы интересно увидеть что будет. Но у нас еще многие пользователи заведены на другие АТС и постепенно будут переведены на Asterisk.

> просто не до конца разобрались в проблеме
Всё может быть :)
6. Олег Ризванов (oleg.rizvanov) 14.06.13 12:10
(5) wondermaker,
Нагрузки в 100 звонков в минуту у нас, пока, не предвидится, хотя, было бы интересно увидеть что будет. Но у нас еще многие пользователи заведены на другие АТС и постепенно будут переведены на Asterisk.

Будет весело, гарантирую :)

С нашей схемой такого не наблюдается, хотя нагрузка выше.

Наверное компонента хорошая :)
7. Fred (Aspirant) 30.01.14 18:35
Тонкая настройка фильтров на основе регулярных выражений/
Как я понимаю это настройка выполнится для конкретного соединения?
Тоесть к примеру такой вариант работы:
Работают через терминальные сессии на сервере. Запускают одну и ту же компоненту dll.
При такой фильтрации каждый пользователь устанавливает свой фильтр и только для себя?



8. Олег Ризванов (oleg.rizvanov) 06.02.14 16:33
(7) Aspirant,
Для каждого экземляра ВК - свой фильтр. Если сеанс пользователя использует 1 экземляр ВК, то соотношение Фильтр:Пользователь как 1:1
9. Dima Ovcharenko (d.ovcharenko90) 30.10.14 18:18
У меня такой вопрос:

разбор регулярного выражения

Dial.{1,}?Begin.{1,}?902|Bridge.{1,}?902|Hangup.{1,}?902


происходит в режиме, когда метасимвол '.' соответствует также переносу строки? По умолчанию в PCRE - не соответствует.

Я пробовал без этого режима тестировать ваше выражение с вашим же текстом события на http://regex101.com/
Без модификатора /s совпадения, естественно, нет

Это правильно? Или я где-то ошибаюсь?
10. Олег Ризванов (oleg.rizvanov) 31.10.14 22:19
Все очень, очень просто - библиотека ROM-Asterisk свободная. Мы очень любим open-source. И мы воспользовались фришной библиотекой PCRE.

ROM-Asterisk умеет все, что умеет PCRE
11. Олег Филиппов (comol) 28.04.15 18:13
(5) wondermaker, (4) oleg.rizvanov, Коллеги, а правильно я понимаю если "Слушает" порядка 50-70 человек то надо уже устанавливать AMI Porxy, потому как обрыв и установка соединения в этом случае дело нормальное, потому как Asterisk Manager "не любит" множественные к нему соединения?
12. Олег Ризванов (oleg.rizvanov) 28.04.15 22:46
(11) comol,
Не факт. Если есть обрывы, то надо разбираться почему они происходят.

Начиная с версии Asterisk 1.8 работа AMI стала куда лучше, чем в 1.6. На версии 11, 13 у меня тоже нареканий нет.

АМИ-прокси - это вариант, но я пока не встречал нормальных прокси без утечек и потерь пакетов. ИМХО, прокси может стать дополнительным гемором.

Какая версия Астериск у вас используется? При каком кол-ве наблюдаете выпадения?
13. Олег Филиппов (comol) 30.04.15 18:29
(12) oleg.rizvanov, 1.8 Обрывы есть... пользователей около 50
14. Олег Филиппов (comol) 30.04.15 18:30
(12) oleg.rizvanov,
разбираться почему они происходят
это Ehtereal или TcpDump имеется ввиду?... Или есть проще варианты?
15. Олег Ризванов (oleg.rizvanov) 01.05.15 01:36
(13) comol,
При 50-ти вроде не должно такого быть.

Может АМИ рвет коннекшн по таймауту записи в клиентский сокет?
По дефолту у АМИ стоит таймаут 0,1 сек (100 мс). Попробуйте поставить 5 сек (5000 мс) или 10.
Если разрывов станет меньше, значит где-то там собака порылась.

P.S.
А вообще, лечить по фотографии - дело неблагодарное. Описали бы проблему детальнее. если есть желание
16. Олег Ризванов (oleg.rizvanov) 01.05.15 01:43
(13) comol,

Параметр называется writetimeout, живет в секции юзера

Вот здесь пример есть

Вот здесь статья которая может пригодиться
17. Олег Филиппов (comol) 05.05.15 19:59
(16) oleg.rizvanov, Спасибо... только изменение конфигурационных файлов и core restart мы чувствую долго согласовывать будем.. Если вообще согласуем... Прокси это совсем плохо, да?
18. Олег Ризванов (oleg.rizvanov) 06.05.15 00:12
(17) comol,

Прокси - это прокси, и хорошо, и плохо. Вот например, HTTP-прокси - это хорошо или плохо?

Как по мне, то хз, но глюки будут точно. Ибо вы вносите в схему дополнительную прокладку
19. Олег Филиппов (comol) 06.05.15 10:56
(18) oleg.rizvanov, Понятно.... А какой лучший прокси если знаете? Или какие вообще в природе существуют...
20. Dmitry_Shelchkov 25.03.16 15:25
Здравствуйте! А подскажите, пожалуйста, можно ли сделать фильтр по двум номерам? т.е. не только по 902, а, например 902 и 903?
21. Олег Ризванов (oleg.rizvanov) 25.03.16 18:53
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа