Обработка CDR/CEL - Очереди на Beanstalk

Обработка CDR/CEL - Очереди на Beanstalk

Одной из часто встречающихся труднорешаемых задач в Asterisk (или VoIP в целом) является задача обработка событий CDR и CEL. Почему эта задача решается трудно? В зависимости от вашей инфраструктуры, проблемы могут возникнуть по одной из причин:

  • Блокировка строк в базе данных (БД);
  • Обработка нескольких входных точек;
  • Обработка постоянно меняющихся данных;
  • Разделение проблемы обработки данных на кластеры;
  • Репликация записей данных между несколькими точками обработки данных;
  • Синхронизация данных;
  • Уникальность и согласованность данных;
  • и т.д.

Основная проблема заключается в том, что при обработке события или CDR оно обрабатывается только один раз.

Asterisk предоставляет несколько бэкендов для обработки записей CDR и CEL. К ним относятся файлы журналов, MySQL, Postgres, ODBC и другие. Тем не менее, все они подвержены тем же проблемам, которые описаны выше.
В одном из наших проектов по разработке распределенной системы, мы столкнулись со следующими проблемами обработки событий CELи CDR:
  • Наша распределенная платформа имела неизвестное количество серверов Asterisk и автомасштабирование в неизвестные сроки;
  • Наша платформа была разделена на несколько облачных зон и регионов;
  • Наша платформа отсылала несколько типов событий, которые требовали различных видов обработки.

Таким образом, нами было принято решение: запись в реляционную СУБД (РСУБД). Результат был плачевным. Обработка была медленной, происходили блокировки записей в БД, и, что хуже всего, становилось все труднее обрабатывать события, предоставленные с множества обработчиков. Решение: Beanstalk.

По своей сути Beanstalkd — упрощенная и легкая система очередей, которая разрабатывалась под нужны Causes. Представляется как менеджер заданий распределенного приложения, который собирает отложенные задачи (отправка почты, различные запросы рода).
Обработка CDR/CEL - Очереди на Beanstalk
Определенные процессы размещают задачи в очередь, а воркеры получают и выполняют задачи из очереди.
Среди основных возможностей beanstalkd:
  • приоритизация;
  • распределенность — несколько серверов beanstalkd работают по принципу Memcached (можно масштабировать);
  • отложенное выполнение (т.з. bury) для последующего выполнения;
  • внешние библиотеки (PHP, Python и многие другие), веб-консоли;
  • таймаут для автоматического помещения в очередь.

Термины и команды beanstalkd

Терминология инструмента отличается от привычных серверов сообщений, того же Gearman, к примеру:
  • jobs — то же, что и сообщения;
  • tubes — очереди, в которые помещаются сообщений для передачи работникам (workers);
  • producers — приложения, которые создают задания (или сообщения);
  • consumers — приложения, которые получают задания из очереди для обработки.

Основных команд у beanstalkd тоже немного:

  • put — добавить новое задание в очередь (в том числе отложено);
  • reserve — получить задание из очереди;
  • delete — удалить задание после выполнения;
  • bury — отложить задание после завершения;
  • kick — вытащить задание из статуса bury и поместить в очередь;
  • release — поставить статус “готово” для задачи после выполнения, сохраняется id и приоритет.
Обработка CDR/CEL - Очереди на Beanstalk
Больше команд и опций на официальной странице системы.
Наша идея для работы была очень простой: записи CDR обрабатывать относительно медленно, записи CEL должны обрабатываться относительно быстро с возможностью получения reserve для работы с клиентами из очереди, а затем удалять delete задание после выполнения и возвращаться к очереди.
Таким образом появились cdr_beanstalk и cel_beanstalk.
Фундаменты beanstalk очень похожи и обеспечивают возможность вставки CDR/CEL-событий непосредственно из Asterisk на удаленный beanstalk сервер.
Естественно мы будем использоваться любимую ОС Debian.

Шаг 1. Установка и настройка Beanstalk

Некоторые из основных дистрибутивов представляют beanstalk как предварительно скомпилированный пакет, в данном случае aptitude:
sudo apt-get install beanstalkd
Сервер станет доступен на порту 11300 (по умолчанию)
Для запуска достаточно выполнить команду:
beanstalkd
После установки демоном beanstalkd также можно управлять как сервисом ОС. Он выполняется в RAM, а для обеспечения fault tolerance запускается с дополнительной опцией:
beanstalkd -b ~/beanstore &
Пишет данные очереди в каталог beanstore, выполнение в фоне.
Если перезапустить beanstalkd с такими же параметрами, то он в первую очередь проверит лог и продолжит выполнение с места остановки.

Демона beanstalkd можно запускать с опциями:

-b DIR   директория для валидации
 -f MS    fsync каждое значение миллисекунд ( -f0 для "always fsync")
 -F       без fsync (по умолчанию)
 -l ADDR  слушать адрес (0.0.0.0 по умолчанию)
 -p PORT  слушать порт (11300 по умолчанию)
 -u USER  стать пользователем и группой
 -z BYTES максимальный размер задания в байтах (65535 по умолчанию)
 -s BYTES размер каждого файла валидации (10485760 по умолчанию)
            (будут округлены до значения, кратного 512 байт)
 -c       уменьшить binlog (по умолчанию)
 -n       не уменьшать binlog
 -v       показать версию
 -V       улучшенный вывод
 -h       показать справку
Ко всему прочему beanstalkd поддерживает клиенты для всех популярных языков и обладает API для создания проприетарных клиентов.

Внимание! Beanstalkd не содержит никакой авторизации и механизмов безопасности, поэтому убедитесь, что вы закрыли используемый порт “наружу”.

Шаг 2. Настройка cdr_beanstalkd.conf

;
; Asterisk Call Management CDR via Beanstalkd job queue
;
; Beanstalkd is a simple job queue server, that is highly versatile and simple to use.
; Beanstalkd includes the capability of using multiple queues at the same time, with priorities.
;
; This module requires that your server has the beanstalk-client library installed. The library
; can be downloaded from - https://github.com/deepfryed/beanstalk-client
;

[general]
enabled = yes
host = 127.0.0.1 ; Specify the remote IP address of the Beanstalkd server
port = 11300 ; Specify the remote PORT of the the Beanstalkd server
tube = asterisk-cdr ; Specify the default CDR job queue to use
priority = 99 ; Specify the default job priority for the queue. This parameter is useful when building
; platform with multiple Asterisk servers, that are used for different functions. For example,
; none billable CDR records can be inserted with a priority of 99, while billable ones be
; inserted with a priority of 1
Вам необходимо раскомментировать строки активации бэкенда. Основные параметры это tube и priority. Бэкенд позволяет вставлять события в одну назначенную tube. Это означает, что все записи CDR будут вставлены в очередь заданий CDR asterisk-cdr. Далее вы можете задать приоритете – чем меньше число, тем выше приоритет. Механизм priority особенно полезен, когда у вас несколько серверов Asterisk с разной функциональностью, для которых требуется разный приоритет обработки. Например сервер Asterisk, который занимается маршрутизацией, требует приоритет выше, чем тот сервер Asterisk, который выполняет функцию голосовой почты.
Проверяем установленную конфигурацию и убедимся что наш CDR-сервер работает:
*CLI> cdr show status
Call Detail Record (CDR) settings
----------------------------------
Logging: Enabled
Mode: Simple
Log unanswered calls: No
Log congestion: No
* Registered Backends
-------------------
Adaptive ODBC
cdr_manager (suspended)
cdr-custom
cdr_beanstalkd
csv
Для конфигурации cdr_beanstalkd.conf используется та же концепция.
После того, как ваша конфигурация будет работоспособна и протестирована, вы сможете использоваться beanstakld клиентские библиотеки для начала обработки ваших заданий. Одна из наиболее функциональных библиотек PHP называется Pheanstalk, не смотря на то, что она старая, обеспечивает все функциональные возможности, которые вы могли бы захотеть.
Общий жизненный цикл beanstalkd выглядит следующим образом:
Обработка CDR/CEL - Очереди на Beanstalk
Общий принцип работы основан на том, что для уникальной обработки, вам необходимо выполнить reserve задание, затем delete когда оно выполнится или release в случае если обработка завершилась неудачно. Приятная мелочь, что вам не нужно беспокоится о целостности очереди или о приоритетах, потому что beanstalkd позаботится об этом за вас. Кроме того, есть возможность настроить beanstalkd таким образом, чтобы он сохранял свою очередь в файл, это полезно когда ваш сервер внезапно выключился, была возможность продолжить обработку без потери данных.

Вопрос-ответ:

Вопрос: У меня нет исходных кодов, хотя они доступны на GitHub. Они все еще в разработке? Когда код будет доступен в исходном пакете Asterisk?
Ответ: Данный функционал станет доступным в следующей версии Asterisk 16. [1] https://gerrit.asterisk.org/#/c/6819/ [2] https://gerrit.asterisk.org/#/c/6841/
Вопрос: Почему за основу взят Beanstalkd? Ведь он не развивается с 2014 года. Есть ли какие плюсы/минусы?
Ответ: Первоначальная версия этого обработчика CDR была заложена еще в 2010 году в Asterisk 1.6. Когда он был создан, он использовался для внутренних проектов Digium, который был заброшен на долгое время. Недавно Digium обновил базу кода для поддержки последней -версии Asterisk и код был направлен на мастер-ветвь. Он немного устарел как технологический инструмент, но до сих пор является жизнеспособным инструментом для использования. Даже PHPAGI не обновляется годами, но по-прежнему является основным инструментом для разработчиков AGI. Стабильность –  самый важный фактор.