忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT 徽章 文库 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 32487 | 回复: 1

F5针对 SIP应用的负载均衡的一次测试过程 [复制链接]

论坛徽章:
0
发表于 2007-10-07 15:35 |显示全部楼层

简介: F5针对 SIP应用的负载均衡 一、 SIP应用负载均衡的背景和功能 SIP( 会话初始协议)的开发目的是用来帮助提供跨越因特网的高级电话业务。因特网电话(IP电话)正在向一种正式的商业电话模式演进,SIP就是用来确保这种 ...
F5针对 SIP应用的负载均衡

一、    SIP应用负载均衡的背景和功能
SIP( 会话初始协议)的开发目的是用来帮助提供跨越因特网的高级电话业务。因特网电话(IP电话)正在向一种正式的商业电话模式演进,SIP就是用来确保这种演进实现而需要的NGN(下一代网络)系列协议中重要的一员。
SIP是IETF标准进程的一部分,它是在诸如SMTP(简单邮件传送协议)和HTTP(超文本传送协议)基础之上建立起来的。它用来建立,改变和终止基于IP网络的用户间的呼叫。为了提供电话业务它还需要结合不同的标准和协议:特别是需要确保传输(RTP),与当前电话网络的信令互连,能够确保语音质量(RSVP),能够提供目录(LDAP),能够鉴权用户(RADIUS)等等。
SIP被描述为用来生成,修改和终结一个或多个参与者之间的会话。这些会话包括因特网多媒体会议,因特网(或任何IP网络)电话呼叫和多媒体发布。会话中的成员能够通过多播或单播联系的网络来通信。SIP支持会话描述,它允许参与者在一组兼容媒体类型上达成一致。它同时通过代理和重定向请求到用户当前位置来支持用户移动性。SIP不与任何特定的会议控制协议捆绑。
SIP中有两个要素:SIP用户代理(user agentSIP网络服务器(proxy server。用户代理是呼叫的终端系统元素,而SIP服务器是处理与多个呼叫相关联信令的网络设备。
现有的负载均衡设备通过记忆SIP协议的CALL-ID来区分进入服务器的SIP访问,从而实现对SIP用户代理类的服务器负载均衡。这时,所有的用户请求均终结在SIP服务器,服务器并不主动对外发起请求。对于负载均衡设备而言,该种SIP服务器的负载均衡最易实现。本功能在F5公司的BIG-IP 4.5版本就已经实现,且用户只要简单的选取SIP 作为persistant持续性方式就可以实现。
但是, SIP网络服务器(proxy server在SIP网络中却占绝大多数,且是真正承载网络负载压力的服务器,是必须采用服务器集群技术的关键要素。而由于SIP proxy server不但要接受用户请求,同时也会发起请求,此种双向数据流的应用几乎所有的负载均衡设备均无法实现。F5公司考虑到这类双向数据流的应用的普遍性,在BIG-IP V9版本中提供了超级灵活的iRule(规则定制)可以比较简单的实现对SIP网络服务器(proxy server的负载均衡,并且可以灵活的支持今后SIP的各类呼叫信息。这也是中外各个移动运营商采用F5公司的BIG-IP作为负载均衡设备的唯一选择的重要原因。
二、    SIP proxy server的负载均衡
首先,让我们来看看proxy server在整个传输过程中的作用:

如图所示,PA和PB是SIP网络中的网络服务器(proxy server),A和B是两个终端用户代理(user agent)。可以看出当PA接受来自A的SIP请求后,会再主动发起向PB的一个SIP请求,该请求得到响应后,PA再回复A的SIP请求。Proxy server PA同时成为SIP服务器端和客户端。
我们将整个传送过程按步骤编号如下:



  其中,包含了两大部分:
1>  作为服务器端,proxy server 响应用户ewa@id.ethz.ch的请求,步骤1、步骤7和步骤8;
2>  作为客户端,proxy server 发起的到sna@ksy112的请求,步骤4、步骤6、步骤9;
其中,步骤1、步骤7和步骤8具有同一个SIP CALL-ID,而步骤4、步骤6、步骤9具有另一个SIP CALL-ID。在单台proxy server的时候,这两部分的绑定是不成问题的,但是当中间的proxy是proxy server 集群时,如何保证数据包发送到同一服务器就成为是否能够完成proxy server的负载均衡的关键了。而其中的关键就是负载均衡设备能够依据CALL-ID,将用户请求1和远端服务器响应6区分开,前者进行必要的负载均衡,而后者必须转发到发出请求4的服务器上。
如图,是我们此次的测试网络结构:


为此,我们采用构筑inbound和outbound两个虚拟服务器分别对应SIP用户发起的请求和SIP proxy服务器发起的请求。
virtual inbound_sip_vs {
   destination 192.168.9.250:5060
   ip protocol udp
   profile my_udp_profile
   pool sip_pool
   rule sipclient
}
这个虚拟服务器对应用户SIP请求


virtual outbound_sip_vs {
   destination any:5060
   ip protocol udp
   translate service disable
   profile my_udp_profile
   rule sipserver
}
这个虚拟服务器对应proxy server外出的请求


profile udp my_udp_profile {
   defaults from udp
   datagram lb enable
}
pool sip_pool {
   member 10.40.90.234:5060
   member 10.40.90.235:5060
}

UDP数据包采用每个数据包单独处理的datagram lb负载均衡方式
对于out_sip_vs,我们采用sipserver 规则来记忆外出的SIP请求③的CALL-ID,这样当响应返回⑤时,系统将不会进行负载均衡而直接转发到原始服务器上。
rule sipserver {
   when CLIENT_DATA {
            if {[scan [UDP::payload] "%s%s" method uri] == 2} {
# 确认获取SIP协议数据包
                if {[regexp {Call-ID:\s*([^\r\n]+)[\r\n]+} [UDP::payload] -> callid] == 1} {
                        # 截获SIP数据包内的Call-ID
                        set lll [list $callid any]
                        # 将SIP数据包内的Call-ID赋值给lll
                        set sss [session lookup uie $lll]
            # 查询服务器外出会话表中是否已有该Call-ID对应的服务器,将其赋于sss
                        if {$sss == ""}  {
                        # 确认服务器外出会话表中无该Call-ID即是新的外出会话
                            session add uie $lll [format "%s:%s" [IP::remote_addr] 5060]
                        # 在服务器外出会话表中添加一行记录Call-ID和对应的发起服务器
                        }
                }
            }
         forward
         # 对于服务器外出请求采用路由方式实现转发
    }
}

对于inbound_sip_vs,我们采用sipclient规则来区分是用户请求①,还是返回的响应⑤。对于前者我们将采用负载均衡将用户请求分配到不同的服务器并记忆Call-ID作为persistant持续性依据保证后续的请求包被送到同一服务器。而对于前者,我们则直接从服务器外出请求列表中取出原有的发起服务器,并将数据包直接转发到发起服务器,从而跳过负载均衡。
rule sipclient {
   when CLIENT_DATA {
            if {[scan [UDP::payload] "%s%s" method uri] == 2} {
               # 确认获取SIP协议数据包
                if {[regexp {Call-ID:\s*([^\r\n]+)[\r\n]+} [UDP::payload] -> callid] == 1} {
                        # 截获SIP数据包内的Call-ID
                        set lll [list $callid any]
                        # 将SIP数据包内的Call-ID赋值给lll
                        set sss [session lookup uie $lll]
                        # 查询服务器外出会话表中是否已有该Call-ID对应的服务器
                        set ppp [persist lookup uie $lll]
                        # 查询持续性表中是否已有该Call-ID对应的服务器
                        if {$sss != "" && $ppp == ""} {
                            # 发现是已有的服务器外出会话
                      use pool sip_pool member $sss
                            # 将数据转发到发出请求的服务器上
                        } else {
                      # 确认非服务器主动发出的外出请求
                            persist uie $callid
                      # 重置计算持续性时间,采用服务器负载均衡
                        }
                }
            }
    }
}

可以看出,由于iRules具有超强的灵活性,可以完全安装用户需求,依据数据包内的任意标识字段进行相应的处理,从而不但可以解决眼前的SIP proxy server的负载均衡问题,也为今后移动应用的特殊需求提供了实现的可能。
在此次SIP测试中,F5的BIG-IP 3400完全满足了用户的要求,实现了SIP proxy server集群,为今后提升SIP服务的处理能力提供了可靠的保证。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/36243/showart_396181.html

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-02-12 10:11 |显示全部楼层
可以使用LVS来代替吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP