opensips是一个成熟的开源SIP服务器,除了提供基本的SIP代理及SIP路由功能外,还提供了一些应用级的功能。opensips可定制各种路由策略,应用于语音、视频通信、IM以及Presence等多种应用。同时opensips性能上是目前最快的SIP服务器之一,可用于电信级产品构建。凭借其可扩展、模块化的系统架构,opensips提供了一个高度灵活的、用户可配置的路由引擎,可以为voice、video、IM和 presence等服务提供强大高效的路由、鉴权、NAT、网关协议转化等功能。由于其稳定高效等特点,opensips已经被诸多电信运营商应用在自己的网络体系中。
opensips的架构开放灵活,其核心功能控制均可通过脚本控制实现,各个功能也通过模块加载的方式来构建。本文将主要介绍其中的负载均衡模块及其应用,并且采用的版本为3.2。
opensips负载均衡模块
“负载均衡”模块用来提供基于负载的通信流量路径选择。简言之,当opensips对发向一组目的地的呼叫请求进行路由选择时,它能够将每个目的地的负载情况(就是正在处理中的呼叫请求总数)记录下来,并将新的呼叫请求发向(当时)具有较少负载的目的地。opensips了解每个目的地的承载能力。它预先配置有每个目的地能够接受的最大负载量。更准确地说,opensips在进行路由选择时,它会选择负载较小的目的地,而不是处理中的呼叫请求总数最小的那个目的地,它所选择的目的地只是当时具有最大的剩余处理能力的目的地。
目的地址配置
负载均衡的目的地址不仅仅是一个单一的ip地址,同样需要包含这个目的地址所能承载的能力和能力上限。例如,我们可能有一组用于提供媒体相关服务的机器,它们当中有些机器是用于转码的,有些用于语音邮箱或者语音会议,有些用于简单的公告发布,还有一些用作PSTN转接终端(PSTN termination)。同时也可能会有一些混合使用的机器,比如同时处理PSTN和转码的机器。所以在目的地地址中的每个目的地提供的是一组不同的服务/资源。
LB模块为每个目的地定义了它所提供的资源,并为它所提供的每一种资源,将其承载能力/最大负载量定义为该目的地为该资源所能提供的最大并发呼叫请求处理数。
在我们实际使用过程中,目的地址的信息是配置在mysql中的load_balancer(默认为该表,可根据需要修改,但表结构须保持一致)表中的,结构如下:
id | group_id | dst_uri | resources | probe_mode | description | attr |
1 | 1 | sip:ip:port | pstn=100 | 1 | … | … |
2 | 1 | sip:ip:port | pstn=100 | 1 | … | … |
3 | 1 | sip:ip:port | pstn=100 | 1 | … | … |
id:表示在表中的编号group_id:表示该资源节点所属的组编号,须作为入参在后续的方法中调用,以指定使用哪一组的资源信息。dst_uri:表示目的地址,须以sip:开头resources:表示该资源所能承载的最大会话数probe_mode:表示探测模式。0-不探测,1-当目标处于不可用状态时,才进行探测,探测成功时,将重新启用。2-一直处于探测中。description:描述信息。attr:可作为参数传递进后续的方法中,根据需要配置。
负载均衡函数调用
lb_is_destination(ip,port,[group],[active],[attrs]])
此方法用来判断当前消息是否是从指定的消息来向过来,一般这里的入参填写数据库中所配置的信息,如果发现是从目的地址过来的时候,说明是从内部节点来的消息,这里就直接透传消息,或者不做处理即可,因为在sip的负载均衡中只是针对初始invite消息。
if( lb_is_destination($si,$sp) )
{
#request from a LB destination
t_relay();
exit;
}
这里的$si, 指的是当前消息源地址,$sp表示当前消息的源端口,这些都是opensips定义好的变量,可以在路由脚本中直接使用。
lb_start(grp,resources[,flags],[attrs])
这是用来寻找最终负载节点的方法,可在目的地址上开启一个新的负载均衡会话,该函数一般在判断完消息来向之后使用,如果发现消息来向来自外部,则调用该方法,寻找负载节点,然后透传该消息即可,注意,这里一般只对初始invite使用。
if( lb_start(1,”pstn”) )
{
send(500,”service full”);
exit;
}
这里表示在组1中寻找支持pstn能力的目的地址,如果找到,则返回负载地址,如果找不到,在路由脚本中则直接返回500,告知前向网元,服务已满,无法处理新的请求。
lb_next([attrs])
这个方法用来继续寻找节点,当我们在调用lb_start(),找到其中最适合的目的地址,并且负载过去后,这个地址如果返回了错误响应(4xx,5xx,6xx),此时表明,寻找到的第一个目的地址未能正确处理该请求,则此时我们需要调用lb_next(),继续寻找下一个合适的目的地址,处理该请求。使用示例如下:
if (t_check_status("(408)|(5[0-9][0-9])")) {
/* check next available LB destination */
if ( lb_next() ) {
t_on_failure("1");
xlog("-----------new dst is $dun");
t_relay();
exit;
}
}
lb_disable_dst()
将当前的负载地址置不可用,一般用在当该来向返回错误响应,如4xx/5xx/6xx等,认为该业务出现问题,不再负载向该节点。使用示例如下:
...
if (t_check_status("(408)|(5[0-9][0-9])")) {
lb_disable_dst();
if ( lb_next() ) {
t_on_failure("1");
xlog("-----------new dst is $dun");
t_relay();
} else {
t_reply(500,"Error");
}
}
...
负载逻辑
LB在选择目的地址时会先根据lb_start(grp,resources[,flags],[attrs])函数中的grp参数在数据库中找到该组的所有目的地址,然后根据resources,从所有的目的地址中挑选合适的目的地址。现假设LB中具有4个目的地/机器1) 提供了30个tran(编码转换)和32个PSTN线路2) 提供了100个vm(语音信箱通道)和19个tran(编码转换)3) 提供了50路vm(语音信箱通道)和300路conf(会议)4) 提供了10个vm(语音信箱通道)、10路conf(会议)、10个tran(编码转换)和32路PSTN线路
当调用lb_start(“1″,”tran;pstn”)时1) 只有机器(1)和机器(4)会被选上,因为他们都提供了编码转换和pstn2) 评估当前占用和可用的情况
已用资源
(1) 编码转换 – 已占用10个通道;PSTN – 已占用18路
(4) 编码转换 – 已占用9个通道;PSTN – 已占用16路
可用资源
(1) 编码转换 – 20个通道可用;PSTN – 14路可用
(4) 编码转换 – 1个通道可用; PSTN – 16路可用
3) 评估最小可用资源
(1) 14 (PSTN)
(4) 1 (tran)
4) 最后选择了机器(1),因为对于使用量最大的资源,它具有最大的可用负载。
Opensips在视频彩铃中的应用
视频彩铃主要分为信令面和媒体面,信令面用于控制会话状态,媒体面主要用于在合适的时机给主叫终端推流,播放视频彩铃。opensips的负载均衡模块主要应用于信令面。
opensips对外直接对接CSCF,接受来自CSCF的请求,然后根据负载情况分配到内部的具体的处理模块中,并且会为每个模块分配最大的会话数,一旦当从CSCF来的请求过大,超过配置的最大会话数时,opensips会直接放通新的请求,防止内部模块因为流量过大而导致业务异常。内部模块是集群模式,opensips同时能够支持对内部模块的动态所扩容处理。
openisps本身为了增强稳定性,采用的是双机模式,他们之间使用keepalived组成双机,当opensips主机发生故障时,在keepalived的作用下,会将虚拟ip飘到备机上,备机可以处理虚拟ip上的消息,以此来达到双机倒换的功能。
结语
opensips的负载均衡是SIP软交换中核心的功能,但是其使用部署也比较复杂,本文档主要介绍负载均衡的基本用法以及在视频彩铃中的应用。
在比较大型的呼叫应用场景中,媒体服务器资源具有不同的支持能力,负载均衡也需要灵活地处理。如果想要了解更多有关opensips的内容,可以进入opensips官网了解更多内容。
作者:叶明雨 | 来源:青榴实验室
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。