Здравствуйте, уважаемые хабравчане.
Вот уже несколько месяцев ковыряюсь в прекрасном продукте FreeSWITCH. Он не перестает меня удивлять функциональностью, надежностью и производительностью (даже в тех областях, в которых от него этого не ждешь).
Один из моих экспериментов, который в скором времени, скорей всего, перейдет в продакшн касался изумительной, с моей точки зрения, функции mod_sofia recover. Функция recover позволяет FreeSWITCH (FS) восстановить вызовы после краша или же, если FS работает в высоко доступном кластере подхватить вызовы на второй ноде! ВНИМАНИЕ! без обрывов вызовов абонентов, как в случае проксировании RTP, так и без него.
Реализуется это достаточно просто, благодаря использованию внешней СУБД и настройкам mod_sofia, отвечающего за SIP стэк. Т.е. mod_sofia хранит всю информацию о текущих вызовах во внешней БД, и при краше у второй ноды кластера есть возможность эти настройки прочесть и подхватить вызовы.
Итак, нам понадобятся:
Я не буду подробно останавливаться на процессе установки FS и выпиливании из него ненужных модулей, все эксперементы будут ставиться на конфигурации по умолчанию. В конце только добавим какой-нибудь гейтвей, для осуществления внешних звонков.
Будем считать, что все что нам нужно установлено, приступим к самому интересному! Ковырянию конфигов.
Установка FS по умолчанию уже вполне звонибельна и для тестов нам ее будет более чем достаточно.
На сервере БД выполняем:
Это создаст БД, в которой FS будет хранить свои настройки.
Наш клайстер будет состоять из 2х рабочих нод и сервера базы данных.
Адрес первой ноды 172.16.100.200
Адрес второй ноды 172.16.100.201
Общий адрес 172.16.100.205
Адрес ДБ сервера 172.16.100.210
Все действия ниже производятся на обоих нодах FreeSWITCH
В файл /etc/odbc.ini вносим параметры подключения к серверу БД
Мы хотим, чтобы FS работал на общем IP, для этого файл freeswitch_base_dir/conf/vars.xml
нужно внести строку:
Для того, чтобы работал recover нужно включить трекинг звонков в sip профилях. Что такое профили прекрасно описано тут. Идем в freeswitch_base_dir/conf/sip_profiles/ и добавляем в настройки обоих профилей (internal, external) строку:
Так же в обоих профилях указываем параметры подключения к серверу БД
Идем в файл freeswitch_base_dir/conf/autoload_configs/switch.conf.xml и добавляем строку или раскоментируем и правим:
При старте FS сам создаст нужные для работы таблицы.
Далее настраиваем heartbeat:
vim /etc/ha.d/authkeys
chmod 600 /etc/ha.d/authkeys
vim /etc/ha.d/ha.cf
vim /etc/ha.d/haresources (на второй ноде нужно поменять хостнейм (fs1 на fs2))
freeswitch::fsrecover — раздел init.d скрипта, который нам подымет наши профили, его мы добавим в следующем шаге
В /etc/init.d/freeswitch между restart и reload добавим
Теперь когда одна из нод грохнется вторая подымет общий IP и перезапустит профили FS, после чего выполнит заветную команду и подхватит звонки.
Для проверки исходящего вызова нам нужно отредактировать dialplan и добавить гейтвей.
В моем примере я буду использовать voip.ms c десятизначным номером. Идем в freeswitch_base_dir/conf/sip_profiles/external/ и создаем файл следующего содержания:
В freeswitch_base_dir/conf/dialplan/default.xml добавляем(поменяйте регулярное выражение и параметры caller-id)
Запускаем демоны:
Стартап скрипт фрисвитча его запустит на обоих нодах, но на неактивной ноде не подымутся профили, т.к. нет IP, на котором они запускаются.
Для тестов берем любой экстеншон из freeswitch_base_dir/conf/directory/default, регистрируемся:
Proxy: 172.16.100.205
username: 1000
password: 1234 (Это default_password, его обязательно надо менять в vars.xml)
Набираем любой номер, в процессе разговора кладем одну из нод и вуаля! Heartbeat обнаруживает, что вторая нода лежит, подхватывает общий IP, запускает скрипт, запуская тем самым неактивные профили. Прерывание медиа потока всего 2-3 секунды, т.е. время, которое уходит у хартбита на перехват ресурсов + 1 секунда в freeswitch:fsrecover
Все. Спасибо за внимание, надеюсь статья кому-то пригодится. Пожелания и предложения более чем приветствуются. В планах есть написать про связку mod_xml_curl, mod_lcr и еще кое что.
П.С. Как принято говорить: ”сильно не пинайте, первая статья”.
Литература:
wiki.freeswitch.org
Вот уже несколько месяцев ковыряюсь в прекрасном продукте FreeSWITCH. Он не перестает меня удивлять функциональностью, надежностью и производительностью (даже в тех областях, в которых от него этого не ждешь).
Один из моих экспериментов, который в скором времени, скорей всего, перейдет в продакшн касался изумительной, с моей точки зрения, функции mod_sofia recover. Функция recover позволяет FreeSWITCH (FS) восстановить вызовы после краша или же, если FS работает в высоко доступном кластере подхватить вызовы на второй ноде! ВНИМАНИЕ! без обрывов вызовов абонентов, как в случае проксировании RTP, так и без него.
Реализуется это достаточно просто, благодаря использованию внешней СУБД и настройкам mod_sofia, отвечающего за SIP стэк. Т.е. mod_sofia хранит всю информацию о текущих вызовах во внешней БД, и при краше у второй ноды кластера есть возможность эти настройки прочесть и подхватить вызовы.
Итак, нам понадобятся:
- FreeSwitch
- Установленная отдельно СУБД (в моем случае mysql)
- unixODBC
- депенденсы, которые потребует FS (описано на вики)
- heartbeat
Я не буду подробно останавливаться на процессе установки FS и выпиливании из него ненужных модулей, все эксперементы будут ставиться на конфигурации по умолчанию. В конце только добавим какой-нибудь гейтвей, для осуществления внешних звонков.
Будем считать, что все что нам нужно установлено, приступим к самому интересному! Ковырянию конфигов.
Установка FS по умолчанию уже вполне звонибельна и для тестов нам ее будет более чем достаточно.
На сервере БД выполняем:
#mysqladmin -u dba_user -p create fs_cnf
Это создаст БД, в которой FS будет хранить свои настройки.
Наш клайстер будет состоять из 2х рабочих нод и сервера базы данных.
Адрес первой ноды 172.16.100.200
Адрес второй ноды 172.16.100.201
Общий адрес 172.16.100.205
Адрес ДБ сервера 172.16.100.210
Все действия ниже производятся на обоих нодах FreeSWITCH
В файл /etc/odbc.ini вносим параметры подключения к серверу БД
[fsw-cnf]
Description = MySQL ODBC Database
TraceFIle = stderr
Driver = MySQL
SERVER = 172.16.100.210
USER = fs-usr
PASSWORD = super_secure_password
OPTION = 67108864
DATABASE = fs_cnf
Мы хотим, чтобы FS работал на общем IP, для этого файл freeswitch_base_dir/conf/vars.xml
нужно внести строку:
<X-PRE-PROCESS cmd="set" data="local_ip_v4=172.16.100.205"/>
Для того, чтобы работал recover нужно включить трекинг звонков в sip профилях. Что такое профили прекрасно описано тут. Идем в freeswitch_base_dir/conf/sip_profiles/ и добавляем в настройки обоих профилей (internal, external) строку:
<param name="track-calls" value="true"/>
Так же в обоих профилях указываем параметры подключения к серверу БД
<param name="odbc-dsn" value="fsw-cnf:fs-usr:super_secure_password"/>
Идем в файл freeswitch_base_dir/conf/autoload_configs/switch.conf.xml и добавляем строку или раскоментируем и правим:
<param name="core-db-dsn" value="fsw-cnf:fs-usr:super_secure_password"/>
Это для core настроек FS.При старте FS сам создаст нужные для работы таблицы.
Далее настраиваем heartbeat:
vim /etc/ha.d/authkeys
auth 1
1 sha1 mega_super_secure_key
chmod 600 /etc/ha.d/authkeys
vim /etc/ha.d/ha.cf
# Логи
logfacility local0
# Таимауты
keepalive 100ms
deadtime 2
warntime 1
initdead 120
# как будут между собой общаться ноды
udpport 694
bcast eth0
# Какие ноды учавствуют в нашем клайстере
node fs1 fs2
# После востановления должны ли возвращаться ресурсы на первую ноду?
auto_failback on
vim /etc/ha.d/haresources (на второй ноде нужно поменять хостнейм (fs1 на fs2))
fs1 IPaddr2::172.16.100.205/255.255.255.0/eth0 freeswitch::fsrecover
freeswitch::fsrecover — раздел init.d скрипта, который нам подымет наши профили, его мы добавим в следующем шаге
В /etc/init.d/freeswitch между restart и reload добавим
fsrecover)
$FS_HOME/bin/fs_cli -x "sofia profile internal start"
$FS_HOME/bin/fs_cli -x "sofia profile external start"
/bin/sleep 1
$FS_HOME/bin/fs_cli -x "sofia recover"
;;
Теперь когда одна из нод грохнется вторая подымет общий IP и перезапустит профили FS, после чего выполнит заветную команду и подхватит звонки.
Для проверки исходящего вызова нам нужно отредактировать dialplan и добавить гейтвей.
В моем примере я буду использовать voip.ms c десятизначным номером. Идем в freeswitch_base_dir/conf/sip_profiles/external/ и создаем файл следующего содержания:
<include>
<gateway name="voipms">
<param name="username" value="your_username" />
<param name="password" value="your_password" />
<param name="proxy" value="montreal|houston|newyork|etc.voip.ms" />
<param name="realm" value="voip.ms" />
<param name="register" value="true" />
<param name="sip_cid_type" value="rpd" />
</gateway>
</include>
В freeswitch_base_dir/conf/dialplan/default.xml добавляем(поменяйте регулярное выражение и параметры caller-id)
<extension name="Outbound 10 Digits">
<condition field="destination_number" expression="^(\d{10})$">
<action application="set" data="effective_caller_id_number=8001231234"/>
<action application="set" data="effective_caller_id_name=800 Number"/>
<action application="bridge" data="sofia/gateway/voipms/$1"/>
</condition>
</extension>
Запускаем демоны:
chkconfig heartbeat on
service heartbeat start
chkconfig freeswitch on
service freeswitch start
Стартап скрипт фрисвитча его запустит на обоих нодах, но на неактивной ноде не подымутся профили, т.к. нет IP, на котором они запускаются.
Для тестов берем любой экстеншон из freeswitch_base_dir/conf/directory/default, регистрируемся:
Proxy: 172.16.100.205
username: 1000
password: 1234 (Это default_password, его обязательно надо менять в vars.xml)
Набираем любой номер, в процессе разговора кладем одну из нод и вуаля! Heartbeat обнаруживает, что вторая нода лежит, подхватывает общий IP, запускает скрипт, запуская тем самым неактивные профили. Прерывание медиа потока всего 2-3 секунды, т.е. время, которое уходит у хартбита на перехват ресурсов + 1 секунда в freeswitch:fsrecover
Все. Спасибо за внимание, надеюсь статья кому-то пригодится. Пожелания и предложения более чем приветствуются. В планах есть написать про связку mod_xml_curl, mod_lcr и еще кое что.
П.С. Как принято говорить: ”сильно не пинайте, первая статья”.
Литература:
wiki.freeswitch.org