Джим Меггелен - Asterisk™: будущее телефонии Второе издание
При использовании статической архитектуры реального времени мы указываем Asterisk, какие файлы хотим загрузить из базы данных, используя в файле extconfig.conf следующий синтаксис:
; /etc/asterisk/extconfig.conf filename.conf => драйвер,базаданных[,таблица]
Если имя таблицы не задано, Asterisk будет использовать имя файла.
Использование директивы preload
Большинство файлов можно загружать посредством статической архитектуры реального времени, но несколько файлов не могут быть загружены при использовании этого метода. Это файлы asterisk. conf, extconfig.conf и logger.conf. Кроме того, файлы manager.conf, cdr.conf и rtp.conf не могут загружаться из статической архитектуры реального времени, если драйверы подключения к базе данных не были загружены до запуска основного ядра Asterisk (потому что архитектура реального времени должна загрузить конфигурационные файлы до того, как модуль начнет читать свою конфигурацию). Поскольку в данной главе используется ODBC, в modules.conf пришлось бы добавить следующие строки: ; /etc/asterisk/modules.conf preload => res_odbc.so preload => res_config_odbc.so
Модуль статической архитектуры реального времени читает настройки статических файлов из базы данных, используя особым образом форматированную таблицу. В PostgreSQL таблица для статической архитектуры реального времени создается с помощью следующего запроса:
CREATE TABLE ast_config (
id serial NOT NULL,
cat_metric int4 NOT NULL DEFAULT 0,
var_metric int4 NOT NULL DEFAULT 0,
filename varchar(128) NOT NULL DEFAULT ''::character varying, category varchar(128) NOT NULL DEFAULT 'default'::character varying, var_name varchar(128) NOT NULL DEFAULT ''::character varying, var_val varchar(128) NOT NULL DEFAULT ''::character varying, commented int2 NOT NULL DEFAULT 0, CONSTRAINT ast_config_id_pk PRIMARY KEY (id)
)
WITHOUT OIDS;
Чтобы понимать, как Asterisk применяет строки базы данных для конфигурации различных загружаемых модулей, дадим краткое описание каждого из столбцов:
cat_metric
Значимость категории в рамках файла. Чем ниже значение, тем выше в файле располагается категория (см. врезку «Несколько слов о значениях»).
var_metric
Значимость элемента в рамках категории. Чем ниже значение, тем выше в списке располагается элемент. Применяется, например, для определения порядка расположения кодеков в файле sip.conf или iax.conf, когда требуется, чтобы disallow=all шел первым (значение 0), за ним - allow=ulaw (значение 1), а далее - allow=gsm (значение 2) (см. врезку «Несколько слов о значениях»).
filename
Имя файла, которое модуль в обычных условиях читал бы с жесткого диска системы (то есть musiconhold.conf, sip.conf, iax.conf и т. д.).
category
Имя раздела файла, такое как [general], но не надо сохранять его в базу данных в квадратных скобках.
var_name
Опция, располагающаяся слева от знака равенства (то есть disallow - это var_name в выражении disallow=all). var_val
Значение опции, располагающееся справа от знака равенства (то есть all - это var_val в выражении disallow=all).
commented
Любое отличное от 0 значение будет рассматриваться так, как если бы перед ним в плоском файле стояла точка с запятой (то есть оно было бы закоммментировано).
Несколько слов о значениях
Значения в статической архитектуре реального времени используются для управления порядком, в котором объекты читаются в память. cat_metric и var_metric можно рассматривать как исходные номера строк в плоском файле. Больший cat_metric обрабатывается первым, потому что Asterisk выполняет сопоставление категорий снизу вверх (вот почему порядок пользователей и равноправных участников может иметь значение в файле sip.conf или iax.conf). Меньший var_metric в рамках категории обрабатывается первым, потому что Asterisk будет обрабатывать порядок опций в категории сверху вниз (например, чтобы обеспечить обработку disallow=all первым, для него в рамках категории должно быть задано меньшее значение, чем для allow).
Возьмем простой файл, который можно загрузить из статической архитектуры реального времени, musiconhold.conf file. Начнем с его перемещения во временную папку:
# cd /etc/asterisk
# mv musiconhold.conf musiconhold.conf.old
Чтобы удалить классы из памяти, необходимо перезапустить Asterisk. После этого, выполнив команду moh show classes, можно убедиться в отсутствии классов: *CLI> restart now *CLI> moh show classes *CLI>
Итак, давайте вернем класс [default] в Asterisk, но теперь загрузим его из базы данных. Установим соединение с PostgreSQL и выполним следующие запросы INSERT:
INSERT INTO ast_config (filename,category,var_name,var_val) VALUES ('musiconhold.conf','general','mode','files'); INSERT INTO ast_config (filename,category,var_name,var_val) VALUES ('musiconhold.conf','general','directory','/var/lib/asterisk/moh'); Убедиться в том, что значения внесены в базу данных, можно, выполнив запрос SELECT:
asterisk=# select filename,category,var_name,var_val from ast_config;
filename | category | var_name | var_val + + +
musiconhold.conf | general | mode | files musiconhold.conf | general | directory| /var/lib/asterisk/moh (2 rows)
И теперь, чтобы указать Asterisk, что необходимо брать данные для musiconhold.conf из базы данных, осталось внести в файл extconfig. conf, находящийся в папке /etc/asterisk, всего одно изменение. Добавим следующую строку в конец файла extconfig.conf и сохраним его:
musiconhold.conf => odbc,asterisk,ast_config Подключимся к консоли Asterisk и выполним перезагрузку: *CLI> module reload
Теперь, выполнив команду moh show classes, можно убедиться, что наши классы для воспроизведения музыки во время ожидания загружаются из базы данных:
*CLI> moh show classes
Class: general
Mode: files
Directory: /var/lib/asterisk/moh
И вот, пожалуйста; musiconhold.conf загружается из базы данных. Точно так же можно организовать загрузку из базы данных других плоских файлов!
Динамическая архитектура реального времени
Динамическая система реального времени используется для загрузки часто изменяющихся объектов: пользователей и равноправных участников SIP/IAX2, очередей и их членов и сообщений голосовой почты. Поскольку эта информация в системе может или меняться, или регулярно дополняться новыми записями, использование мощи базы данных позволит нам загружать ее по мере необходимости.
Все настройки архитектуры реального времени описываются в файле /etc/asterisk/extconfig.conf, но динамическая архитектура реального времени имеет строго определенные конфигурацонные имена, такие как sippeers. Описание равноправного участника SIP (SIP peer) выполняется в следующем формате: ; extconfig.conf
sippeers => драйвер,базаданных[,таблица] Имя таблицы является необязательным параметром. Если он не задан, Asterisk будет использовать предопределенное имя (то есть sippeers) как имя таблицы для поиска данных. В нашем примере для хранения информации равноправных участников SIP будет использоваться таблица ast_sip peers.
Помните, что у нас имеются и равноправные участники SIP (SIP peer), и пользователи SIP (SIP user); peer - это конечные точки, которым мы отправляем вызовы, а user направляют вызовы нам. friend - это сокращенная запись, определяющая оба типа конечных точек.
Таким образом, чтобы сконфигурировать Asterisk на загрузку всех равноправных SIP-участников из базы данных в режиме реального времени, необходимо записать примерно следующее:
; extconfig.conf
sippeers => odbc,asterisk,ast_sipfriends Чтобы также загружать наших SIP-пользователей из базы данных, задаем следующее:
sipusers => odbc,asterisk,ast_sipfriends
Вероятно, вы обратили внимание, что и для sippeers, и для sipusers используется одна и та же таблица. В ней есть поле типа (точно так же, как если бы тип был определен в файле sip.conf), поэтому для извлечения информации мы можем задавать тип user, peer или friend. При описании таблицы для пользователей и равноправных участников необходимо как минимум следующее:
В обязательных полях port, regseconds и ipaddr Asterisk сохраняет регистрационную информацию равноправного участника, чтобы знать, куда направлять вызов. Предполагается, что хост является dynamic; однако, если бы равноправный участник был static, нам пришлось бы заполнять поле ipaddr самостоятельно. Поле port является необязательным. Если для него используется стандартный порт, указанный в разделе [general], поле regseconds остается пустым. Для SIP-друга можно определить множество других опций, таких как ID вызывающего абонента. Чтобы добавить эту информацию, требуется просто вставить дополнительный столбец callerid в таблицу. Другие опции, которые могут быть определены для соединения SIP типа friend, можно найти в файле sip.conf.sample.
Хранение записей параметров вызовов
Записи параметров вызовов (Call Detail Records, CDR) содержат информацию о вызовах, прошедших через систему Asterisk. Более подробно они обсуждаются в главе 13. Хранение CDR - один из самых популярных примеров использования баз данных в Asterisk, потому что в этом случае с CDR проще работать (например, можно отслеживать несколько систем Asterisk в одной таблице).
Создадим в нашей базе данных таблицу для хранения CDR. Зарегистрируемся на сервере PostgreSQL с помощью приложения psql: # psql -U asterisk -h localhost asterisk
Password:
И создадим таблицу asterisk_cdr:
asterisk=> CREATE TABLE asterisk_cdr (
id bigserial NOT NULL, calldate timestamptz,
Задание параметра systemname для глобальных уникальных идентификаторов
CDR состоят из уникального идентификатора и нескольких полей информации о вызове (включая источник и канал назначения, продолжительность вызова, приложение, выполняемое последним, и т. д.). В кластере серверов Asterisk теоретически возможно дублирование уникальных идентификаторов, поскольку каждая система Asterisk учитывает только саму себя. Чтобы решить эту проблему, можно автоматически добавлять идентификатор системы в начало уникального ID. Для этого введем дополнительную опцию в файл /etc/asterisk/asterisk.conf и зададим идентификатор для каждого из серверов: [options]