背景
最近在研究sip代理服务,国内大部分推荐使用opensips,第一时间安装opensips来学习,实际在使用中发现opensips 3.x的坑很多,很多功能在2.x版本上有,但是在3.x上还未实现。光是sip做代理服务转发请求到freeswitch上,3.x版本配置上就没有一个能成功使用的示例,配置都是2.x的,很多参数还不适配。整了2天都没搞明白,果断弃坑,选用kamailio,此时才发现kamailio是多么友好。
安装kamailio
本次使用centos7.9系统,kamailio的版本是5.6。
安装步骤比较简单,按照网上流程都能安装成功。 我选择的是源码安装,需要注意的是make cfg
时,要选择安装一些模块 既可以 make include_modules="db_mysql xxx" cfg
选择安装的模块,也可以打开 ./src/modules.list 找到 exclude_modules,把需要安装的模块从这里删除。 之后就make && make install 。
配置sip代理服务
运行kamailio
kamailio的配置文件位置: /usr/local/etc/kamailio/
改kamactlrc的mysql连接,和kamailio.cfg里的DBURL,之后kamctl start
运行服务.如果报错:ERROR: PID file /run/kamailio/kamailio.pid does not exist -- Kamailio start failed
查看 /var/log/message 日志,看看报错日志。
配置dispatcher 代理
官方文档配置参考: https://github.com/kamailio/kamailio/blob/master/src/modules/dispatcher/doc/dispatcher.cfg
kamailio代理服务使用的是dispatcher模块,配置方式有两种:- 使用dispatcher.list
在kamailio的配置位置下,新建dispatcher.list, 写入需要代理的fs服务:
# $Id$
# dispatcher destination sets
# setit(int) destination(sip uri) flags(int,opt) priority(int,opt) attributes(str,opt)
# Freeswitch IPS
1 sip:192.168.40.143:5080
1 sip:192.168.30.100:5080
full example:
1 sip:127.0.0.1:5080 0 0 duid=abc;socket=udp:192.168.0.125:5060;my=xyz;ping_from=sip:myproxy.com
flags:
1: inactive destination
2: temprary trying destination
4: admin disabled destination
8: probing destination (sending keep alives)
16: skip DNS A/AAAA resolve at startup
attributes:
duid: It must be an unique value to identify a destination
maxload: defining the upper limit of active calls per destination
weight: beteen 1 and 100
rweight: between 1 and 100
socket: used to set the sending socket for the gateway
sockname:
ping_from:
然后在kamailio.cfg配置中,加入dispatcher使用
loadmodule "dispatcher.so"
modparam("dispatcher", "list_file", "/usr/local/etc/kamailio/dispatcher.list")
modparam("dispatcher", "table_name", "dispatcher")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "xavp_dst", "_dsdst_")
modparam("dispatcher", "xavp_ctx", "_dsctx_")
modparam("dispatcher", "ds_ping_from", "sip:dispatcher@192.168.40.45")
modparam("dispatcher", "ds_ping_interval", 60)
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_timer_mode", 1)
- 使用mysql
#!ifndef DBURL
#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio"
#!endif
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", DBURL)
modparam("dispatcher", "table_name", "dispatcher")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "xavp_dst", "_dsdst_")
modparam("dispatcher", "xavp_ctx", "_dsctx_")
modparam("dispatcher", "ds_ping_from", "sip:dispatcher@192.168.40.45")
modparam("dispatcher", "ds_ping_interval", 60)
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_timer_mode", 1)
参数解释:
ds_ping_method: 可以自定义ping方法,默认INFO
ds_hash_expire: 如果在指定时间内(默认7200s)BYE未收到,就删掉这个路由。
ds_hash_initexpire: 如果在指定时间内(默认7200s)INVITE的200ok未收到,就删掉这个路由。
配置转发
request_route
最后添加route(DISPATCH)
route(REGISTRAR); if ($rU==$null) { # request with no Username in RURI sl_send_reply("484","Address Incomplete"); exit; } # dispatch destinations route(DISPATCH);
# Dispatch requests
route[DISPATCH] {
# round robin dispatching on gateways group '1'
if(!ds_select_dst("1", "4")) {
send_reply("404", "No destination");
exit;
}
xdbg("--- SCRIPT: going to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");
t_on_failure("RTF_DISPATCH");
route(RELAY);
exit;
}
# Try next destionations in failure route
failure_route[RTF_DISPATCH] {
if (t_is_canceled()) {
exit;
}
# next DST - only for 500 or local timeout
if (t_check_status("500")
or (t_branch_timeout() and !t_branch_replied())) {
if(ds_next_dst()) {
xdbg("--- SCRIPT: retrying to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");
t_on_failure("RTF_DISPATCH");
route(RELAY);
exit;
}
}
}
在route[DISPATCH]
中ds_select_dst("1", "4")
"1":代表配置的freeswitch中的setid
"4": round-robin 轮询选择。
ds_select_dst 轮询配置 参考文档: https://kamailio.org/docs/modules/5.6.x/modules/dispatcher.ht...
结论
通过配置两个freeswitch, 选择适当的分配方式可以把请求按照一定的比例分发到两个freeswitch上。另外如果其中一个freeswitch服务死掉,kamailio检测到之后,会把之后的请求全都转到另外的一个freeswitch服务上。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。