Яндекс.Метрика

Asterisk Эксперт очно/онлайн

Asterisk Эксперт очно/онлайн с 16 октября по 17 октября

Количество
свободных мест

4 Записаться

Курсы по Mikrotik MTCRE

Курсы по Mikrotik MTCRE с 8 декабря по 11 декабря

Количество
свободных мест

6 Записаться
Эволюция одного проекта от DIALPLAN до ARI
144
Доклад
Данила Евграфов
Эволюция одного проекта от DIALPLAN до ARI
скачать презентацию

Эволюция одного проекта от DIALPLAN до ARI

Введение

Этот доклад я подготовил, чтобы вы могли посмотреть на наши ошибки и, возможно, не допускать их у себя. А может быть, найдёте для себя какие-то интересные архитектурные решения. Будет много схем с архитектурой. Я хотел добавить код, но в итоге не стал, потому что, честно говоря, кому нужен мой «кривой» код на PHP и Python? Поэтому просто схемы.

С чего всё началось в 2015 году

Изначально у нас был виджет обратного звонка, работавший довольно просто: там был практически статичный диалплан, куда подставлялись переменные. Он их воспроизводил и мог соединить звонок дальше с менеджером. На этом, в принципе, всё. На базе этой идеи мы решили создать новый продукт для автоматизации исходящих и входящих звонков.

Первая версия системы

В начале у нас был воркер на Python, который соединялся с Asterisk по AMI, передавал туда несколько переменных, а вся логика уже управлялась в диалплане. Процесс звонка выглядел так:

  1. Из базы выбирался звонок
  2. Воркер по AMI инициировал Originate в Asterisk
  3. Asterisk отправлял события (callstart и прочие) обратно воркеру
  4. Воркер собирал информацию и писал её в базу

Диалплан был довольно статичным: проигрывал первый файл (по переменной), а дальше было всего три варианта нажатий и номер менеджера, с которым можно соединиться по нажатию «1».

Плюсы и минусы этой схемы

  • Из плюсов — простой код с минимумом логики.
  • Из минусов — сложность отладки и кастомизации сценариев, ведь диалплан — штука специфическая, и не каждый разработчик легко и быстро в нём разберётся. Кроме того, на тот момент было лишь три ветки IVR, что сильно ограничивало гибкость системы.

Добавляем PHP-скрипты

Следующим шагом было ввести скрипты на PHP, чтобы расширить возможности кастомизации диалплана. Инициация звонков всё так же шла на Python по AMI, но теперь с помощью AGI-скриптов на PHP мы могли запрашивать из базы данные сценариев и делать больше действий.

Процесс звонка при этом выглядел так же, но появилась новая часть с обработкой на PHP. Диалплан стал сложнее: сначала воспроизводился ролик (по переменной), потом шёл пользовательский ввод (цифры, слова, распознавание через IVR), а дальше система могла отправить SMS, проиграть другой ролик или соединить с менеджером.

Плюсы и минусы новой схемы

  • Из плюсов — гибкая кастомизация, и разработчикам не нужно глубоко лезть в диалплан, чтобы дорабатывать приложение.
  • Из минусов — теперь у нас два языка (Python и PHP), каждый звонок обрабатывается отдельным процессом (PHP-скрипт запускается на каждый вызов), и всё по-прежнему работает на одном сервере, что затрудняет масштабирование.

Вводим роутер и упрощаем логику

Чтобы решить проблемы с масштабированием, мы добавили новый компонент — роутер (на Python). Он подключался к базе, а с воркерами, которые общались с Asterisk по AMI, держал соединение по сокету. Так появилась возможность создавать несколько воркеров. При этом PHP-скрипты перестали обращаться напрямую к базе: теперь вся информация о звонке подавалась скриптам через переменные от воркера.

Проблема распознавания речи и переход на EAG

Сначала для распознавания речи мы использовали обычные AGI-скрипты. Минус в том, что они не позволяют обрабатывать звук в потоке. Нужно было записывать файл 2–10 секунд, потом отправлять его в службу распознавания (Яндекс, Google и т. д.) и лишь потом реагировать. В итоге взаимодействие получалось «топорным», робот отвечал с задержкой.

Чтобы это исправить, мы перешли на EAGI. Там можно работать со звуком в потоке и сразу реагировать на слова пользователя. Плюс — более «живое» общение. Минус — работа со звуком через файловый дескриптор, что упирается в ограничения по количеству одновременных звонков на Asterisk. Кроме того, не было буферизации на стыке роутера и Asterisk: если что-то ломается, звонки могут копиться и «ронять» всё приложение.

Внедряем брокер сообщений RabbitMQ

Чтобы решить проблему узких мест, мы добавили RabbitMQ и систему очередей. Теперь, если появляется перегрузка, звонки уходят в очередь, а воркеры их обрабатывают позже. Это не очень приятно для пользователей, которым хочется моментальной связи, но лучше, чем полное падение системы. Параллельно мы добавили DataUpdater — ещё один воркер, который занимается обновлением информации о звонке в базе.

С помощью очередей стало гораздо удобнее масштабироваться. Но при этом сохранялось несколько минусов: по-прежнему EAGI и его ограничения по дескрипторам, два языка в проекте, и каждый звонок обрабатывался отдельным процессом.

Переход на ARI

Чтобы убрать ограничения EAGI и отказаться от PHP, мы решили переписать логику на ARI (Asterisk REST Interface). Да, проблемы с файловым дескриптором ушли, а PHP мы совсем убрали, оставив один Python. Но при этом пришлось писать гораздо больше кода, потому что в ARI нужно самому управлять каналами, мостами, проигрыванием роликов, записью звонков и т. д. — если раньше в AGI можно было вызвать готовое приложение (Dial, Playback, MixMonitor), то теперь всё реализуется вручную.

Из плюсов — асинхронность, гибкость, один язык разработки. Из минусов — нет готовой библиотеки для ARI под Python 3, и мы писали свою. Плюс к этому у нас пока плохо автоматизирован процесс развёртывания: все сервера (а их уже около 50) мы поднимаем вручную, и это превращается в довольно большую боль.

Планы на будущее: Kubernetes, Kamailio и Docker

Мы планируем упаковать Asterisk в Kubernetes, добавить Kamailio, чтобы Asterisk-узлы масштабировались как медиасерверы, а Kamailio служил бы фронтендом, общаясь напрямую с провайдерами. Тут, конечно, много нюансов, связанных и с Docker, и с Kamailio, но мы надеемся, что справимся с этими задачами уже в ближайшее время.

Заключение

В ходе развития проекта мы прошли путь от простого статического диалплана с минимальной логикой к гибкой, асинхронной и масштабируемой системе на базе ARI, устранив ограничения EAGI и отказавшись от PHP в пользу единого Python-стека; поэтапное введение роутера и RabbitMQ позволило разгрузить узкие места и добавить очереди, но потребовало собственной библиотеки и усложнило развёртывание, а переход к ARI — написания большого объёма кода для управления каналами и мостами; в будущем планируется контейнеризация Asterisk в Kubernetes с фронтендом Kamailio и автоматизацией выпуска через Docker, что должно обеспечить автоматические масштабирование и более простой деплой.

Ежегодная конференция по Asterisk 2025!

Билеты уже в продаже!

Остались вопросы?

Я - Виталий Шелест, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.

Наши
клиенты

Посмотреть все