четверг, 26 ноября 2009 г.

Утилиты телефонного биллинга

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

Представленное решение включает в себя следующие файлы: набор тиклевых библиотек, некоторое множество SQLite баз данных, веб-сервер AOL Server с adp-скриптами для генерации web-интерфейса, набор консольных утилит и некоторые другие ресурсы.

Система обрабатывает миллионы звонков в месяц на десктопном оборудовании без каких-либо дополнительных действий по оптимизации баз данных. Для обработки большего числа звонков необходимо ежесуточно выполнять команду VACUUM для БД статистики за текущий месяц. При еще больших масштабах может потребоваться разделять БД не по месяцам, а по неделям или даже дням. "Ядро" биллинговой системы выполняет обработку около 500 звонков в секунду в расчете на 1 ядро процессора (тестировалось на Intel(R) Core(TM)2 Quad CPU Q6700 @ 2.66GHz); при этом один звонок может биллинговаться по двум-трем тарифам. Итак, на сервере с 1 процессором Core Quad можно обработать около 500 звонков ежесекундно (предполагается, что коллекторы запущены на этой же системе и также потребляют процессорное время). Обработка звонков выполняется пакетно, изменяя интервал от минимального 3 секунды и до сколь угодно большого, можно "сгладить" пиковую нагрузку. Для большинства реальных применений такой производительности более чем достаточно. Примечание: нагрузочные тесты для коллекторов будут выложены позднее.

Примечание
В открытом доступе выложены коллекторы и набор утилит для создания БД и проч. Система биллингования в настоящее время является закрытым продуктом.

Установка утилит

Используемая операционная система (ОС) - debian lenny. При необходимости можно пересобрать пакеты для других операционных систем или просто установить из исходников наших пакетов (не забыв патчи), но мы рекомендуем именно debian.

Репозиторий для Debian lenny:

deb http://mobigroup.ru/debian/ lenny main contrib non-free
deb-src http://mobigroup.ru/debian/ lenny main contrib non-free


Установить ключ с подписью репозитория:

sudo aptitude install debian-mobigroup-keyring


Следует установить следующие пакеты:

sudo aptitude install mbg-telephony-dataset mbg-telephony-tacacs-utils mbg-telephony-m200-utils


В настоящий момент в репозитории выложена сборка -comintern пакетов коллекторов, в которую включены "обертки" для скриптов с настроенными путями к лог-файлам, файлам БД и проч. Рекомендуем воспользоваться именно этими пакетами, выполнив соответствующую настройку или написав свои скрипты для вызова базовых утилит.

sudo aptitude install mbg-telephony-dataset \
mbg-telephony-tacacs-utils-comintern \
mbg-telephony-m200-utils-comintern


Пакет mbg-telephony-dataset содержит утилиты управления БД трафика (создание, биллингование), mbg-telephony-tacacs-utils - обеспечивает сбор данных с демонов tacacs (АТС Cisco) и mbg-telephony-m200-utils - выполняет сбор данных с демонов callbuilder (АТС m200).

Примечание: для работы "ядра" биллинга используются также следующие пакеты из вышеназванного репозитория:

sudo aptitude install sqlite3 libsqlite3-tcl tcl8.5

Но для работы описываемых здесь утилит достаточно и стандартных версий этих пакетов.

Файлы и каталоги
Основным параметром является корневая директория размещения каталогов MBGROOT, где в поддиректориях располагаются вышеперечисленные файлы, за исключением некоторых утилит, полностью независимых от основной системы (в т.ч. коллекторов). Структура директорий фиксирована, так что этого параметра достаточно, чтобы найти любой файл системы.

Любые функции системы могут быть вызваны из скриптов, не обращаясь к веб-интерфейсу. Ниже приведено описание некоторых скриптов из комплекта поставки системы, предназначенных для сбора и предварительной обработки траффика, сохранения его в БД и биллингования, а также начисления абонентской платы и выполнения заданий по расписанию по переключению услуг и тарифных планов.

Базы данных
Для понимания работы скриптов следует отметить, что система имеет основную БД, в которой хранится описание пользователей, услуг и проч., и набор БД с трафиком, разделенных по месяцам (типы трафика разделяются по директориям, телефония хранится в директории telephony). Коллекторы сбора данных с АТС сразу же производят месячную ротацию БД. При биллинговании необходимо и достаточно работать с активной БД траффика (примечание: в случае использования распределенной архитектуры следует выполнить биллингование за прошлый месяц по завершению сбора статистики с удаленных узлов). БД траффика допускают слияние - можно объединить две базы в одну без образования дубликатов, но при этом следует учитывать, что результаты биллингования не должны объединяться (допустимо объединять только таблицы telephony_log). Пробиллингованные записи имеют соответствующий флаг (telephony_log.is_new=0), так что уже обработанные записи при запуске биллингатора игнорируются, следовательно, его можно запускать сколь угодно часто (в том числе, можно биллинговать в реальном времени, например, с интервалом 30 секунд, установив такой же или меньший интервал синхронизации для коллекторов).

Коллекторы
Коллекторы для сбора данных имеют настраиваемый интервал синхронизации (параметр командной строки -interval), который указывает промежуток времени между операциями записи собранной статичтики в основную БД (накапливаемая в течении этого интервала статистика хранится в памяти коллектора). При невозможности выполнить синхронизацию коллектор сообщает об ошибке в лог и пропускает синхронизацию до следующего раза, продолжая накапливать данные. Коллектор способен в течении многих дней и даже месяцев аккумулировать данные при невозможности синхронизации - при возникновении такой ситуации просто устраните причину и данные будут синхронизированы (используется эффективный по объему и быстродействию формат хранения в памяти, так что 1 Гб ОЗУ достаточно для хранения статистики миллионов звонков). В целях обеспечения отказоустойчивости рекомендуется запуск нескольких коллекторов на разных хостах,
сохраняющих данные каждый в свою БД с периодическим слиянием этих БД в основную. Объединение статистики двух баз может быть выполнено следующей командой:

sqlite3 /mnt/host1/2009-10-01.db '.dump telephony_log'|egrep "BEGIN|INSERT|COMMIT" \
|sqlite3 2009-10-01.db

Здесь данные траффика из /mnt/host1/2009-10-01.db (вы можете как примонтировать удаленную ФС в /mnt/host1/, так и просто скопировать удаленный файл) копируются в файл 2009-10-01.db (напомним, дубликаты автоматически игнорируются).

Upd. Также вы можете воспользоваться предоставляемой нами утилитой для master-slave репликации SQLite баз.

Заметим, что поставляемые в комплекте коллекторы умеют как работать в режиме демона, собирая статистику в реальном времени, так и импортировать сохраненные на диск лог-файлы. Это позволяет настроить биллинговую систему на работу в режиме реального времени с обеспечением отказоустойчивости (запустив по завершению месяца импорт всех дисковых логов, на тот случай, если произошли какие-то потери - актуально в случае отсутствия резервных хостов сбора данных) или выполнять ежедневную/ежемесячную обработку накопленных логов (если вам по каким-либо причинам предпочтителен именно этот вариант).

Коллектор демона tacacs+ (сбор данных с cisco)
telephony_agent_tacacs

$ /usr/bin/telephony_agent_tacacs
Коллектор логов АТС cisco, выдаваемых программой tacacs+ в сокет (режим -demon 1) или
сохраненных на диск (режим -demon 0).
Результат обработки сохраняется в виде лог-файлов универсального формата в указанной директории.
Используйте программу следующим образом:
/usr/bin/telephony_agent_tacacs -host хост -interval интервал_сохранения_секунд \
-dataset директория_хранения_баз [-ports "порт1 порт2 ... "]
или
cat лог_файл | /usr/bin/telephony_agent_tacacs -dataset директория_хранения_баз

Параметры
-host
-ports
-interval
нужно указывать только в режиме демона (-demon 1).


Пример скрипта для запуска в режиме демона:
telephony_agent_tacacs-demon

/usr/bin/telephony_agent_tacacs -host nebu -interval 30 -ports 1881 -demon 1 \
-dataset /srv/dataset/telephony


Коллектор АТС m200
telephony_agent_callbuilder

$ ./telephony_agent_callbuilder
Коллектор логов АТС м200, выдаваемых программой callbuilder в сокет (режим -demon 1) или
сохраненных на диск (режим -demon 0).
Результат обработки сохраняется в виде лог-файлов универсального формата в указанной директории.
Используйте программу следующим образом:
/usr/bin/telephony_agent_callbuilder -host хост -interval интервал_сохранения_секунд \
-dataset директория_хранения_баз [-ports "порт1 имя_атс1 порт2 имя_атс2 ... "]
или
cat лог_файл | /usr/bin/telephony_agent_callbuilder -dataset директория_хранения_баз \
-ports "stdin имя_атс"

Параметры
-host
-interval
нужно указывать только в режиме демона (-demon 1).


Пример скрипта для запуска в режиме демона:
telephony_agent_callbuilder-demon

/usr/bin/telephony_agent_callbuilder -host localhost -interval 30 -demon 1 \
-dataset /srv/dataset/telephony \
-ports "10211 vk-pbx-1 10221 nati-txe-1 10231 vat-pbx-1 10241 vk-pbx-2 10251 \
m9-txe-1 10261 vat-pbx-2 10271 vk-txe-1"


Биллингование телефонного трафика

MBGROOT=/var/www/billing2 /usr/bin/telephony_rating_monthly \
`sqlite3 :memory: "select date('now','start of month')"`
или
MBGROOT=/var/www/billing2 /usr/bin/telephony_rating_monthly_force \
`sqlite3 :memory: "select date('now','start of month')"`

При вызове telephony_rating_monthly_force будет произведен полный пересчет за текущий месяц. Пересчет за один день не может быть выполнен, т.к. стоимость звонков в общем случае зависит от значений кумулятивных счетчиков.
Аналогично может быть выполнено биллингование за любой месяц.

Начисление абонентской платы

MBGROOT=/var/www/billing2 /usr/bin/billing_cost_daily \
`sqlite3 :memory: "select date('now','-1 day')"`
или
MBGROOT=/var/www/billing2 /usr/bin/billing_cost_daily_force \
`sqlite3 :memory: "select date('now','-1 day')"`

При вызове billing_cost_daily_force будет выполнено переначисление абонентской платы для всех услуг за указанный день.
Аналогично может быть выполнено начисление за любой день.

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

MBGROOT=/var/www/billing2 /usr/bin/billing_cost_daily `month 2009-11-01|xargs`


Поясним список аргументов, передаваемый billing_cost_daily:

$month 2009-11-01|xargs
2009-11-01 2009-11-02 2009-11-03 2009-11-04 2009-11-05 2009-11-06 2009-11-07 \
2009-11-08 2009-11-09 2009-11-10 2009-11-11 2009-11-12 2009-11-13 2009-11-14 \
2009-11-15 2009-11-16 2009-11-17 2009-11-18 2009-11-19 2009-11-20 2009-11-21 \
2009-11-22 2009-11-23 2009-11-24 2009-11-25 2009-11-26 2009-11-27 2009-11-28 \
2009-11-29 2009-11-30


Планировщик управления услугами пользователей

MBGROOT=/var/www/billing2 /usr/bin/billing_planner_daily \
`sqlite3 :memory: "select date('now')"`

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

Запуск коллекторов
Пример конфигурации /etc/inittab для телефонного биллинга на АТС m200 и cisco

sc1:2:respawn:/usr/bin/scomm 172.17.7.2 10000 10001 -outdir /srv/log/ats1
sc2:2:respawn:/usr/bin/scomm 213.148.6.162 10000 10002 -outdir /srv/log/ats2
...

sp1:2:respawn:/usr/bin/spider-start -scommport 10001 -serverport 10101 -outdir /srv/log/ats1
sp2:2:respawn:/usr/bin/spider-start -scommport 10002 -serverport 10102 -outdir /srv/log/ats2
...

cb1:2:respawn:/usr/bin/callbuilder-start -spiderport 10101 -outdir /srv/log/ats1 -serverport 10210
cb2:2:respawn:/usr/bin/callbuilder-start -spiderport 10102 -outdir /srv/log/ats2 -serverport 10220
...

ag1:2:respawn:/bin/su mobi -c "/usr/bin/telephony_agent_tacacs-demon \
> /srv/log/telephony_agent_tacacs.log"
ag2:2:respawn:/bin/su mobi -c "/usr/bin/telephony_agent_callbuilder-demon \
> /srv/log/telephony_agent_callbuilder.log"


Здесь используются вспомогательные скрипты, описанные ниже.
callbuilder-start

#!/bin/sh

/usr/bin/callbuilder -spiderip 127.0.0.1 -rotation 3 -str2boff -cdrformat 10 $@


spider-start

#!/bin/sh

/usr/bin/spider -scommip 127.0.0.1 -rotation 4 $@


Пакетный импорт логов демона tacacs+ (с АТС cisco)
Скрипт содержит в себе пути к лог-файлам, т.к. предназначен для работы в виде обертки к соответствующему коллектору. Логи могут быть в текстовом виде и сжатые gzip.

telephony_import_tacacs

#!/usr/bin/tclsh8.5
# парсит набор логов такакса, распаковывая их при необходимости

set src /root/tacacs/
set dst /srv/dataset/telephony

foreach fname [glob $src/*] {
if {[file extension $fname] eq {.gz}} {
puts "importing gzipped: $fname"
set cat zcat
} else {
puts "importing plain: $fname"
set cat cat
}
exec $cat $fname | /usr/bin/telephony_agent_tacacs -dataset $dst
}


Пакетный импорт логов демона callbuilder (с АТС m200)
Скрипт содержит в себе пути к лог-файлам, т.к. предназначен для работы в виде обертки к соответствующему коллектору. Логи могут быть в текстовом виде и сжатые gzip. Для загрузки лишь части лог-файлов предусмотрено задание масок года и месяца аргументами командной строки.

telephony_import_callbuilder

#!/usr/bin/tclsh8.5
# парсит набор логов m200, распаковывая их при необходимости
# первый аргумент - шаблон номера месяца, второй аргумент - шаблон номера года

set src /srv/log
set dst /srv/dataset/telephony

# можно указать набор аргументов, из которых будет составлен шаблон имени файла
foreach fname [glob $src/*/cdr_log_mon*[lindex $argv 0]*_*[lindex $argv 1]*.log] {
set ats_name [lindex [file split $fname] 3]
if {[file extension $fname] eq {.gz}} {
puts "importing gzipped log $ats_name: $fname"
set cat zcat
} else {
puts "importing plain log $ats_name: $fname"
set cat cat
}

exec $cat $fname | /usr/bin/telephony_agent_callbuilder -dataset $dst /
-ports "stdin $ats_name"
}


Трансляция лога демона tacacs+
При организации распределенной системы демон tacacs+ может находиться на хосте, отличном от того, на котором запущен соответсвующий коллектор. В этом случае мы рекомендуем следующее решение, которое корректно работает с ротируемыми файлами и позволяет подключение одного и более коллекторов:


sudo socat EXEC:"/usr/bin/tail -F -n 0 /var/log/tacacs" \
TCP4-LISTEN:9999,bind=localhost,su=nobody,fork,range=127.0.0.1/32,reuseaddr


Проверить работу транслятора можно так:

telnet localhost 9999


В приведенной команде из соображений безопасности разрешено подключение только с localhost, а далее порт может быть проброшен средствами ssh, что защитит передаваемые между распределенными офисами данные. Также можно настроить подключение из нужной подсети или с нужного хоста, если все происходит в одной доверенной сети (в т.ч., организованной с помощью VPN-подключений).

Ссылки
Структура базы телефонного биллинга
Телефонный биллинг: тариф "Направление посекундно"
Использование adp-wrapper в биллинге

Комментариев нет:


(C) Alexey Pechnikov aka MBG, mobigroup.ru