五、负载均衡配置与应用
前言
OpenSIPS作为一个高效的SIP服务器,势必经常作为网关或其它类型的SIP代理服务器使用,主要做信令处理。这样一来,对消息的分发、负载将是一个核心的功能。
1、OpenSIPS两种常用场景
1.1 作为注册的SIP服务器
通常sip终端都需要注册到某台SIP服务器上(就像手机要连接到基站),以实现呼出和呼入的功能。如图
注册在OpenSIPS上的SIP终端发起的呼叫请求将发送到OpenSIPS,OpenSIPS根据路由脚本配置使用load_balancer(负载均衡)模块或dispatcher(调度模块)将呼叫请求转发到其他sip服务器或网关上。反之当sip服务器或网关呼叫注册在OpenSIPS上的终端时,会呼入到OpenSIPS(只有OpenSIPS有被叫SIP终端的AOR信息),然后opensips再呼叫SIP终端。这是就是一个典型的注册服务器。
1.2 作为SIP代理服务器
OpenSIPS可能很多时候都是做为一个sip代理服务器。如图
OpenSIPS作为代理服务器时,可以将代理两边的请求根据路由配置互相转发。通常也是使用load_balancer或dispatcher模块做分发。单做信令的转发,不处理其它业务。
2、OpenSIPS负载均衡
OpenSIPS负载均衡原理这里不再赘述,可以参考文末的官网文档,里面有详细的介绍。这里只对负载均衡实现的关键地方做解释。
2.1 配置负载均衡目的地集
OpenSIPS负载均衡由load_balancer模块实现,配置是在load_balancer表中配置的,如下图load_balancer表字段:
各个设置项的意义:
id:该行负载配置的唯一id,当使用MI命令将某个处于enable=no(不可用)状态的负载服务器置为可用时,会用到这个id。
group_id:负载地址组ID,标识一个目的地集。负载均衡时是以目的集为单位做负载的。
dst_uri:负载目的地URI,必须以”sip:”开头。
resources:配置资源类型已及能容纳的最大负载数。
probe_mode:探测目的地服务器模式,后面会详细介绍。
description:备注。
OpenSIPS启动的时候,会从load_balancer表中读出目的地集,保存到内存中。如果OpenSIPS启动后对目的地集做了修改,可以使用MI命令重新加载目的地集,使其生效:
opensipsctl fifo lb_reload
2.2 负载均衡相关函数
设置了负载均衡目的集,只是配置了负载路由数据。真正执行负载均衡的操作,是在路由脚本中调用负载均衡的函数。
这里介绍几个常用的负载均衡函数,更多函数由于篇幅有限,这里不再赘述,可以参考文末的官网文档。
lb_is_destination(ip,port[,group[,active]]):判断指定的ip,port是否和group 1指定的目的地集中的某一个URI匹配,如果匹配成功,返回true。
...
if (lb_is_destination("$si", "$sp", "1") ) {
# request from a LB destination
}
...
lb_disable_dst():将当前请求的负载目的地址置为不可用,后续请求将不会负载到该地址(除非探测成功)。(OpenSIPS 1.x版本该函数名为lb_disable)。
...
if (t_check_status("(408)|(5[0-9][0-9])")) {
lb_disable_dst();
...
}
...
lb_count_call(ip,port,grp,resources[,undo]):重新计算ip,port,resource指定的负载目的地负载数,供负载均衡算法使用。
...
if (lb_is_destination("$si", "$sp") ) {
# inbound call from destination
lb_count_call("$si", "$sp", "-1", "conference");
}
...
load_balance(grp,resources[,flags]):真正执行负载均衡的函数,grp指定负载的目的地集,resource指定匹配目的地集中的某个资源。
...
# 将来自group 1的呼叫负载均衡到group 2的pstn资源地址
if ( lb_is_destination("$si", "$sp", "1") ) {
if ( ! load_balance("2", "pstn") ) {
send_reply("500", "Service full");
exit;
}
}
...
2.3 探测负载目的地服务器可用性
对负载到的服务器进行探测是有必要的,因为肯定不希望往一个不可用的服务器去发送请求,这样既浪费时间,也会让请求失败。使用探测可以让OpenSIPS主动发现目的地服务器是否可以可以处理请求,避免做无意义的转发。
前面讲到了OpenSIPS负载均衡配置里的配置字段probe_mode,probde_mode字段用于配置当前行目的地服务器的可用性的探测模式。可配置的值有三个,分别对应三种探测模式:
0:从不探测目的地服务可用性。
1:仅当目的地服务不可用时,才进行探测。如果探测成功,自动将该地址置为可用。
2:实时发起探测请求,不管目的地是否可用。探测失败自动将目的地置为不可用,测试成功则自动将服务置为可用。
一般将probe_mode置为1。
同时也可以设置探测的间隔、探测方法和有效的响应码:
...
modparam("load_balancer", "probing_interval", 60)
modparam("load_balancer", "probing_method", "INFO")
modparam("load_balancer", "probing_reply_codes", "501, 403")
...
探测需要被探测服务器(UAS)的支持,如果对端没有响应或者响应码没有包含在probing_reply_codes的列表中,该服务器为都将置为不可用,将不再负载到它。
2.4 使用MI查看负载均衡信息
通过opensipsctl脚本文件执行MI命令查看(需要加载mi_fifo模块),如./opensipsctl fifo lb_list
lb_reload - 强制OpenSIPS从DB中重新载入所有的配置信息
lb_resize - 修改一个目的地某资源的最大承载能力
lb_status - 修改目的地的状态(可用/不可用),例如将id为12的目的地置为可用:./opensipsctl fifo lb_status 12 1
3、负载均衡实战应用
以前面讲到的OpenSIPS两种常用场景中的第二种,作为SIP代理服务器为例,进行负载均衡配置的实例讲解。
这里的实例场景如图
OpenSIPS作为网关,FreeSWITCH呼出经过OpenSIPS转发,从落地网关呼入也经过OpenSIPS转发,OpenSIPS要做的就只是将两边的请求分别负载均衡到另一边。
3.1 目的地集配置
配置如图
FreeSWITCH的目的地集id(group_id)为1,落地网关的目的地集id为2。resources都是“pstn”。探测模式(probe_mode)都设置为1。
3.2 路由逻辑配置
主路由中对INVITE请求进行负载均衡:
路由的逻辑是如果呼入的源地址匹配Gateway目的地集,就将呼叫负载均衡到FreeSWITCH目的地集,反之则相反。如果都不匹配,则认为是非法请求并返回403。
负载请求路由失败处理:
如果请求负载失败,且返回标识服务器有问题的错误码,则将该负载地址置为不可用,重新负载到下一个目的地(如果有的话)。如果load_balance函数返回失败,则一般意味着负载的这个目的地集都不可用了。
这样就完成了一个简单的OpenSIPS代理服务器的配置。
小结
负载均衡是一个经常会用到的功能,但从全篇的叙述中也可以看出实际配置并不是很复杂(至少在这个例子上是)。熟悉用法可以更有效的应对多变的系统架构需求,实现可拓展性更高的系统。
更多参考官方文档:
http://www.opensips.org/html/docs/modules/2.3.x/load_balancer.html#idp5562896
https://www.oschina.net/translate/tutorials-loadbalancing-1-9?cmp&p=1#