背景介绍
kamailio 的dispatcher模块提供负载均衡功能,可以采用轮询,负载上的权重,通话负载分发和哈希方式。
该模块比较轻量,适合高并发场景。但是不能分发REGISTER请求。
它和opensips的dispatcher不一样,opensips的dispatcher可以分发REGISTER请求。
它更像是opensips的load_balancer。
这个模块既可以使用数据库,也可以使用文件来配置。官方文档地址:dispatcher
kamailio的版本:
version: kamailio 5.8.5 (x86_64/linux)
重要参数解析
|
|
重要函数
ds_select_dst(set, alg[, limit])
从地址集中选择一个地址,然后把地址设置到$du,
- set
表dispatcher的
setid - alg
负载均衡算法,可多个叠加:
- “0”: 哈希
callid - “1”: 哈希
from URI - “2”: 哈希
to URI - “3”: 哈希
request-URI user - “4”: 轮询
- “5”: 哈希
authorization-username,如果没有此字段,使用轮询 - “6”: 随机
- “7”: 哈希
PVs,必须设置hash_pvar - “8”: 使用
dispatcher表里按照priority排序的gateway - “9”:
权重分发,使用dispatcher表里按照weight排序的gateway - “10”: 使用
通话负载分发,必须设置ds_hash_size和dispatcher表的attrs添加duid,速度很快 - “11”: 使用
相对权重分发,dispatcher表的attrs添加rweight, 相对于权重分发,如果有gateway不活跃了,每次会重新计算权重 - “12”: 分发所有节点
- “13”: 延迟分发
ds_ping_latency_stats, 使用的是轮询分发
- “0”: 哈希
ds_next_dst()
获取下一个地址,并设置$du。
ds_set_dst()
把当前的地址设置为$du。
ds_select_domain(set, alg[, limit])
从地址集中选择一个地址,然后重写R-URI里的host和Port,其他参数和ds_select_dst一致。
ds_next_domain()
获取下一个地址,并设置R-URI。
ds_set_domain()
把当前的地址设置为R-URI。
ds_select(set, alg[, limit])
从地址集中选择一个地址,存在XAVP变量里,不会重写R-URI和$du
ds_select_routes(rules, mode [, limit])
按照规则从地址集中选择一个地址
- rules
匹配规则,格式为
grp1=alg1;grp2=alg2 - mode
选择的地址推到哪里
- ‘0’,’d’,‘D’: 修改$du
- ‘1’,‘r’,‘R’: 修改R-URI
- ‘2’,‘x’,‘X’: 存储在XAVP变量
ds_mark_dst([state])
标记上次使用的地址状态
- state
- “a”,“A”: 活跃状态
- “i”,“I”: 非活跃状态
- “t”,“T”: 尝试状态
- “p”,“P”: 可探测状态
实战
本次测试的场景是:
- 软电话1008注册到freeswitch A(
172.18.11.187)上, A配置网关转发请求到kamailio (172.16.4.111) - 1008拨打1003, kamailio(
172.16.4.111)收到请求, dispatcher分发给freeswitch B(172.16.4.113)或 freeswitch C(172.16.4.114) - 两个软电话分别向freeswitch B和freeswitch C注册1003
- B或者C收到请求,拨打软电话,电话接通
从文件读取
- dispatcher.list
|
|
这里要介绍一下attributes参数:
- class=4 接受错误码为400~499的响应
- strip=3 从被叫号码(R-URI)中去除前3位
- prefix=86 在被叫号码(R-URI)前加上86
- duid=abc 唯一标识目标节点
- maxload=30 最大负载值,超过则拒绝
- weight=5 1~100,权重,总和为100,权重越大,请求越多
- rweight=5 1~100,相对权重,总和为100
- socket=udp:127.0.0.1:5060
定义分发请求的socket,覆盖
ds_default_socket - socketname=xxx 定义分发请求的socket name
- ping_from
定义ping的
FromURI,覆盖ds_ping_from - obproxy
- latency
- 配置示例:
|
|
测试效果
ping
kamailio 分别往两个节点发送OPTIONS请求
- 172.16.4.113机器:

- 172.16.4.114机器:

正常拨打电话
可以看到ds_select_dst配置的是轮询,所以不管第一通172.16.4.113是否接通,第二通都会转到172.16.4.114节点
注意: 一定不要配置modparam("dispatcher", "use_default", 1), 否则不管配置的策略是什么,都只会往一个节点发送请求。
当其中一个节点停掉
停掉172.16.4.113节点的freeswitch,在dispatcher未标记此节点为非活跃状态之前,请求还是会发往此节点的。

dispatcher标记172.16.4.113状态为非活跃状态之后,所有的请求只会转到172.16.4.114节点。

存在的问题
dispatcher模块目前没有找到配置可以让服务一启动就开始ping节点。
这就会导致服务启动后,在ping的定时器开始之前,如果有请求过来,不会分发请求。
当然可以缩短ds_ping_interval间隔,但是这样的话,ping的频率会变高。