Привет!
Пользователь Malamut поделился с нами замечательным способом балансировки вызовов через несколько сим-карт. В один из моих первых проектов передо мной вставала такая же задача. У меня не было тогда большого опыта, но была бурная фантазия. Я решил задачу балансировки сим-карт весьма необычным способом.
Дано:
VoIP-сервер на FreeBSD 9.0, asterisk 11, 2x Addpac GS1002, используюся 4 сим-карты Beeline с предоплаченным лимитом в 300 минут каждая. Трафик на мобильные звонки очень большой, в первый месяц тестового периода первая симка превысила лимит в 2 раза, четвертая почти не использовалась. Встал вопрос о балансировке каналов
Решение:
Первым делом выносим контекст с сотовыми исходящими в отдельный файл. Пишем в extensions.conf
#include gsm_exten_1.conf
В общий контекст добавляем
include => mobile
в файле gsm_exten_1.conf прописываем паттерн на мобильные (здесь упрощенный вариант, у меня эти файлы очень обьемные, так как прописано много паттернов именно на мобильные моего региона, остальные также идут через sip-провайдера, брал отсюда )
[mobile]
exten => _89XXXXXXXXX,1,NoOp(${CALLERID(num)})
same => n,MixMonitor(${RECORD_PATH}/${UNIQUEID}.wav,,${WAV2MP3} ${RECORD_PATH} ${UNIQUEID})
same => n,Dial(SIP/9001/${EXTEN},,tkr)
same => n,GotoIf($[${DIALSTATUS}=ANSWER]?h:a)
same => n(a),Dial(SIP/9002/${EXTEN},,tkr)
same => n,GotoIf($[${DIALSTATUS}=ANSWER]?h:b)
same => n(b),Dial(SIP/9003/${EXTEN},,tkr)
same => n,GotoIf($[${DIALSTATUS}=ANSWER]?h:c)
same => n(c),Dial(SIP/9004/${EXTEN},,tkr)
same => n,GotoIf($[${DIALSTATUS}=ANSWER]?h:d)
same => n(d),Dial(SIP/to-sip/${EXTEN},,tkr)
same => n(h),Hangup
Вроде все понятно — пытается пустить звонок сначала через симки с первой по порядку, если все заняты, отправляет через провайдера.
Копируем этот файл 3 раза, именуем соответственно:
cd /usr/local/etc/asterisk/
cp gsm_exten_1.conf gsm_exten_2.conf
cp gsm_exten_1.conf gsm_exten_3.conf
cp gsm_exten_1.conf gsm_exten_4.conf
Далее меняем в каждом файле порядок перебора сим-карт. Мне было удобно сделать это через любимый vi (первый регексп — чтобы не путаться):
/%s/900/1900
/%s/19001/9002
/%s/19002/9003
/%s/19003/9004
/%s/19004/9001
:wq
И так далее. Для удобства восприятия — начертите квадрат 4х4
1|2|3|4
2|3|4|1
3|4|1|2
4|1|2|3
В итоге у нас должно получиться 4 файла с разным порядком перебора сим-карт.
Вы уже догадались, что будет дальше =) Пишем скрипт rotate_script.sh (не забудьте права на выполнение):
#!/usr/local/bin/bash
#Rotation
i=1
mv /usr/local/etc/asterisk/gsm_exten_1.conf /usr/local/etc/asterisk/gsm_exten_5.conf
until [ $i -eq 5 ]
do
mv /usr/local/etc/asterisk/gsm_exten_$[$i+1].conf /usr/local/etc/asterisk/gsm_exten_$i.conf
i=$[$i+1]
done
#Reload your Dialplan
/usr/local/sbin/rasterisk -x "dialplan reload" > /dev/null
И забиваем его в cron
0 6 * * * root /usr/local/etc/asterisk/rotate_script.sh >/dev/null 2>&1
Готово! В итоге у нас каждое утро меняется порядок перебора сим-карт при исходящем вызове, этим и достигается баланс.
Примечания :
Пост не претендует на звание «Лучший и единственно верный способ балансировки каналов», а скорее описывает нестандатность
Еще один UPD:
На следующем сервере я использовал макрос и GotoIfTime. Сейчас, к сожалению, у меня нет доступа к нему, как получу — опишу в отдельной статье и добавлю сюда ссылку.
А вообще IMHO идеальный способ балансировки мобильных — шлюзы GoIP. constnw88 прав, у меня есть настроенный одним транком, с такими же 4мя билайновскими симками, и судя по счетам в бухгалтерию, звонки на нем действительно распределяются равномерно.
Автор: Sl1mShady