Хочу рассказать про некоторые хитрости с очередями в asterisk к которым я пришел решая задачи с отзвоном. Прошу иметь ввиду, что я начинающий специалист и те хитрости которые «открыл» давно решены тем или иным способом. Тем не менее вероятно эти сведения тоже кому-то пригодятся.
Основным условием было — использование только стандартного функционала без обращения к внешним скриптам.
В исходной задаче было несколько неумных шлюзов (без собственных очередей) с двумя и более каналов в каждом, через которые требовалось отзваниваться с той или иной степенью равномерности.
queues.conf
extensions.conf
Добавились пиры с неограниченым явно количеством каналов, требовалось как то их описать для очереди. Попутно выяснилось, что таким образом можно управлять количеством исходящих звонков — сколько каналов распишем, столько и будет звонков одновременно.
queues.conf
extensions.conf
Имеем два пира — основной и запасной. Соответственно звоним на первый пока не достигнем установленных нами ограничений, при превышении плавно переходим на запасной. Либо первый по каким то причинам становится недоступен — тогда сразу переходим на запасной.
queues.conf
extensions.conf
Не забываем перезапускать asterisk (
При стратегии
В принципе при наличии необходимости а также фантазии / смекалки можно делать интересные конструкции — контроль входящей / исходящей нагрузки, резервирование (двойное и более), различные варианты перебора каналов, ну и комбинации вышеперечисленного. Надеюсь кому-то пригодится.
Основным условием было — использование только стандартного функционала без обращения к внешним скриптам.
Очередь из локальных каналов
В исходной задаче было несколько неумных шлюзов (без собственных очередей) с двумя и более каналов в каждом, через которые требовалось отзваниваться с той или иной степенью равномерности.
queues.conf
[queue-out]
strategy=rrmemory
autofill=yes
ringinuse=no ; система не должна звонить на канал который уже используется иначе каналы будут затыкаться
member => Local/out11@dialout
member => Local/out12@dialout
member => Local/out21@dialout
member => Local/out22@dialout
extensions.conf
exten => _X.,1,NoOp()
same => n,Set(_NEXTEN=${EXTEN}) ; передаем номер в очередь
same => n,Queue(queue-out,r)
same => n,Hangup
[dialout]
exten => out11,1,Dial(SIP/gate1/01${NEXTEN}) ; таким образом можно формировать номер для статической очереди
same => n,Hangup
exten => out12,1,Dial(SIP/gate1/02${NEXTEN})
same => n,Hangup
exten => out21,1,Dial(SIP/gate2/01${NEXTEN})
same => n,Hangup
exten => out22,1,Dial(SIP/gate2/02${NEXTEN})
same => n,Hangup
Очередь из локальных каналов — вариант 2 и контроль нагрузки
Добавились пиры с неограниченым явно количеством каналов, требовалось как то их описать для очереди. Попутно выяснилось, что таким образом можно управлять количеством исходящих звонков — сколько каналов распишем, столько и будет звонков одновременно.
queues.conf
[queue-out]
strategy=rrmemory
autofill=yes
ringinuse=no
; вариант для 14 исходящих каналов
; сколько каналов реально - неизвестно или неограничено, данным конфигом мы заставляем систему
; использовать до 14 каналов одновременно
member => Local/out01@dialout
member => Local/out02@dialout
member => Local/out03@dialout
member => Local/out04@dialout
...
member => Local/out12@dialout
member => Local/out13@dialout
member => Local/out14@dialout
extensions.conf
exten => _X.,1,NoOp()
same => n,Set(_NEXTEN=${EXTEN}) ; передаем номер в очередь
same => n,Queue(queue-out,r)
same => n,Hangup
[dialout]
exten => _outXX,1,Dial(SIP/provider1/${NEXTEN}) ; формируем двухзначный номер канала
same => n,Hangup
Очередь из локальных каналов — вариант 3 и резервирование
Имеем два пира — основной и запасной. Соответственно звоним на первый пока не достигнем установленных нами ограничений, при превышении плавно переходим на запасной. Либо первый по каким то причинам становится недоступен — тогда сразу переходим на запасной.
queues.conf
[queue-out]
strategy=linear ; другой тип распределения звонков
; -в заданном порядке, всегда обрабатывается с начала списка, первый будет работать не разгибая спины-
autofill=yes
ringinuse=no
; 30 основных, 20 запасных - количество для примера, указывайте столько, сколько требуется вам
member => Local/prov1out01@dialout
member => Local/prov1out02@dialout
member => Local/prov1out03@dialout
---
member => Local/prov1out29@dialout
member => Local/prov1out30@dialout
member => Local/prov2out01@dialout
member => Local/prov2out02@dialout
member => Local/prov2out03@dialout
---
member => Local/prov2out19@dialout
member => Local/prov2out20@dialout
extensions.conf
exten => _X.,1,NoOp()
same => n,Set(_NEXTEN=${EXTEN}) ; передаем номер в очередь
same => n,Queue(queue-out,r)
same => n,Hangup
[dialout]
exten => _prov1outXX,1,Dial(SIP/provider1/${NEXTEN})
same => n,Hangup
exten => _prov2outXX,1,Dial(SIP/provider2/${NEXTEN})
same => n,Hangup
Проблемы
Не забываем перезапускать asterisk (
service asterisk restart
или core restart now
из консоли) после изменения параметров очереди — module reload
или queue reload all
недостаточно — изменения будут показаны но не будут использоваться (статус Invalid в списке участников).При стратегии
linear
участники очереди через короткое время становились неактивными (канал будто засыпает). Так и не выяснил в чем проблема, решил костылем в виде создания динамической очереди и периодическим пересозданием участников. Может кто то сталкивался и решил? Отпишите в комментах.Итог
В принципе при наличии необходимости а также фантазии / смекалки можно делать интересные конструкции — контроль входящей / исходящей нагрузки, резервирование (двойное и более), различные варианты перебора каналов, ну и комбинации вышеперечисленного. Надеюсь кому-то пригодится.
Поделиться с друзьями
Комментарии (4)
eyt5297
30.03.2017 19:07Вообще не понял,
… решая задачи с отзвоном
что это за задачи? Если задача делать исходящие вызовы, то использовать для этого очереди полный бред.andrey465
30.03.2017 19:24имеем 10 исходящих каналов и 20 (для примера, сильно больше количества каналов) желающих прямо сейчас позвонить (допустим час пик в офисе)
решил попробовать реализовать это на очередях именно потому что там все второстепенные вещи уже решены,
ну а остальное просто результат экспериментов, может быть оно вам интересно, а может вы уже давно имеете свою киллер фичу и смеетесь над тем как кто то снова пытается закручивать гайки пассатижами :)
antirek
Не понял, зачем нужны эти каналы от prov1out01 до prov1out20?
Вы же можете использовать GROUP и GROUP_COUNT для ограничения количества исходящих в одном exten или нет?
andrey465
Основной особенностью решения является именно использование очереди для вызовов. Остальное просто приятные дополнения в виде решения задач которые решаются и другими способами.