Хочу рассказать про некоторые хитрости с очередями в 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)


  1. antirek
    23.03.2017 07:59

    Не понял, зачем нужны эти каналы от prov1out01 до prov1out20?
    Вы же можете использовать GROUP и GROUP_COUNT для ограничения количества исходящих в одном exten или нет?


    1. andrey465
      23.03.2017 10:26

      Основной особенностью решения является именно использование очереди для вызовов. Остальное просто приятные дополнения в виде решения задач которые решаются и другими способами.


  1. eyt5297
    30.03.2017 19:07

    Вообще не понял,

    … решая задачи с отзвоном
    что это за задачи? Если задача делать исходящие вызовы, то использовать для этого очереди полный бред.


    1. andrey465
      30.03.2017 19:24

      имеем 10 исходящих каналов и 20 (для примера, сильно больше количества каналов) желающих прямо сейчас позвонить (допустим час пик в офисе)
      решил попробовать реализовать это на очередях именно потому что там все второстепенные вещи уже решены,
      ну а остальное просто результат экспериментов, может быть оно вам интересно, а может вы уже давно имеете свою киллер фичу и смеетесь над тем как кто то снова пытается закручивать гайки пассатижами :)