王小飞

  Qunar软件工程师,主要从事后端开发工作。个人博客地址:https://www.jianshu.com/users/0d5a83b32e8f/latest_articles

  随着出境旅游的需求不断攀升,出境WIFI、当地玩乐、在线向导等服务受到了更多客户青睐,去哪儿需要在游客走出国门之后,做好从接机、联系当地向导到落地接待等整体服务升级,才能赢得口碑,留住客户。

  如何让游客在国外也能找到回家的感觉,随时随地、轻轻松松地和去哪儿取得联系,在遇到困难的时候,能够及时地向去哪儿寻求帮助,是去哪儿一直在努力提升的地方。

  为了保证游客在国外也能和国内无缝衔接,去哪儿App的用户可以直接通过免费网络电话拨打国内的客服电话。在没有任何宣传推广的情况下,上线7天已经有超过30%的用户选择网络电话入口呼叫接入,这个数据显示用户对于网络电话的认可度是很高的。

  

  下面我们来看一下网络电话的整体解决方案。

  一、VOIP介绍

  VOIP即网络电话,Voice over Internet Protocol,通过把语音信号经过数字化处理、压缩编码打包、通过网络传输,然后解压、把数字信号还原成声音,让通话对方听到。 话音从源端到达目的端的基本过程是: 声 -- 电转换:通过压电陶瓷等类似装置将声波变换为电信号。

量化采样:将模拟电信号按照某种采样方法(比如脉冲编码调制,即PCM)转换成数字信号;

封包:将一定时长的数字化之后的语音信号组合为一帧,随后,按照国际电联(ITU-T)的标准,这些话音帧被封装到一个RTP(即实时传输协议,Realtime Transport Protocol)报文中,并被进一步封装到UDP报文和IP报文中。

传输:IP报文在IP网络由源端传递到目的端 去抖动:去除因封包在网络中传输速度不均匀所造成的抖动音 拆包 电声转换 一个完整的、可以大规模商用运营的IP电话系统包括如下一些技术(暂不完全):寻址 话音编解码 回声消除和回声抑制 传输 IP报文时延控制功能 去抖动 IP报文的去抖动(de-jitter)功能 。

  二、VOIP与传统电话的比较

  简单地来说,VOIP网络电话免费(流量、wifi),传统电话更稳定点。不过现在网络电话行业发展快,很多产品稳定性都超过了传统电话,好比mimicall、vp3000等,所以现在越来越多的人习惯了使用网络电话去进行沟通。

  三、开源软PBX(软交换)的选择

  国内比较流行和拥有活跃用户群的是FreeSwitch(https://freeswitch.org/)和Asterisk(https://www.asterisk.org/),由于之前对Asterisk有一定的应用经验,所以选择了Asterisk。二者都基于sip协议。

  四、客户端开源sip协议库的选取

  目前比较流行的开源的SIP协议库是PJSIP(https://www.pjsip.org/),它实现了SIP、SDP、RTP、STUN、TURN和ICE。PJSIP作为基于SIP的一个多媒体通信框架提供了非常清晰的API,以及NAT穿越的功能。PJSIP具有非常好的移植性,几乎支持现今所有系统:从桌面系统、嵌入式系统到智能手机。PJSIP同时支持语音、视频、状态呈现和即时通讯。PJSIP具有非常完善的文档,对开发者非常友好支持。

  五、调研评估和Demo搭建

  目前市场上对于voip的应用已经比较成熟,好多公司都在做。微信电话本等的推出说明voip完全可行。相对于去哪儿呼叫中心更好的服务于去哪儿用户解决海外用户拨打人工服务的困难,尽最大努力降低用户的成本,voip完全可行。

  1)Demo的快速搭建

  找一台linux机器首先下载安装pjsip软件 安装过程这里不做过细讲解

  用ldconfig命令 验证pjsip的动态链接是否创建

  ldconfig -p | grep pj

  

  安装Asterisk 13(注意只有12以上才支持了pjsip)

  这里注意在编译的时候其实可以查询系统的位数,我的是64位所以直接指定了64,查询指定的命令如下:

  ARCH=$(getconf LONG_BIT | grep “64”)

  ./configure –libdir=/usr/lib${ARCH}

  用make menuselect命令选择安装的模块

  做选择需要编译安装的modules,查看确保pjsip相关的module已选择

  

  然后make config 命令是将asterisk作为linux service的服务

  还有一点就是Asterisk 13 requires pjsip >= 2.4. 所以选取版本的时候也 需要注意。

  2)demo客户端软件选取

  PjSua是开源的客户端代码,同时支持ios和android等主流操作系统,做测试用的话eyeBeam,X-Lite,Blink 都可以作为PC客户端,Blink PC客户端做tls测试的时候比较方便。

  这里可以同时下载eyeBeam,X-Lite两台互拨便于测试。

  3)Asterisk的配置

  Demo可以配置两个测试的分机号(可以认为是用户名和密码)

  配置是在 /etc/asterisk/pjsip.conf 中

  监听地址端口配置为本机ip和5061端口,协议配置成udp

  分别再配置两个号 8005和8006

  [transport-udp]

  type=transport

  protocol=udp

  bind=0.0.0.0:5061

  [8005]

  type=endpoint

  context=from-external

  disallow=all

  allow=ulaw

  transport=transport-udp

  auth=8005

  aors=8005

  [8005]

  type=auth

  auth_type=userpass

  password=8005

  username=8005

  [8005]

  type=aor

  max_contacts=1

  [8006]

  type=endpoint

  context=from-external

  disallow=all

  allow=ulaw

  transport=transport-udp

  auth=8006

  aors=8006

  [8006]

  type=auth

  auth_type=userpass

  password=8006

  username=8006

  [8006]

  type=aor

  max_contacts=1

  4)拨号方案的配置

  拨号方案的配置在 /etc/asterisk/extensions.conf 中 增加配置

  [from-external]

  exten => _80XX,1,NoOp()

  same => n,Dial(PJSIP/${EXTEN})

  启动asterisk

  service asterisk start

  控制台连接

  sudo asterisk -rvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

  注册分机8005 8006

  

  Asterisk 控制台输出

  

  拨打测试 戴上耳机就可以听到你的声音啦

  demo用例图

  

  

  六、Asterisk 负载均衡的搭建

  完美的线上解决方案是不允许单点的出现,作为pbx 也是一样。

  负载均衡软件选取,sip层的负载均衡可以选取硬件,但是成本原因我们可以用软件代替,行业中有不少做sbc的厂家,提供硬件和软件的解决方案,我们可选取kamailio (https://www.kamailio.org/w/) 或者opensips (https://www.opensips.org/),其实二者是一家,不同的分支而已 其中的故事我就不在这里说了,这里我们选取 kamailio。

  1)kamailio安装

  安装过程这里不做过细讲解 这里需要注意将kamailio做成service服务启动方式或者init脚本启动方式需要做以下操作,同时需要注意权限问题

  cp pkg/kamailio/rpm/kamailio.init /etc/init.d/

  mv /etc/init.d/kamailio.init /etc/init.d/kamailio

  chmod 755 /etc/init.d/kamailio

  /etc/init.d/kamailio start

  2) 配置asterisk的转发

  cd /usr/local/etc/kamailio/

  vim dispatcher.list

  1 sip:192.168.0.1 0 1 weight=50

  1 sip:192.168.0.2 0 1 weight=50

  vim kamailio.cfg(kamailio配置比较多官方有文档(https://www.kamailio.org.cn/data/pages/cookbooks/4.3.x/stable.html)这里列举主要的配置)

  listen=udp:192.168.0.3:5060

  modparam("dispatcher", "list_file", "/usr/local/etc/kamailio/dispatcher.list")

  Route配置中加入

  if(!ds_select_dst("$var(dispatcher_group)", "9"))

  {

  send_reply("404", "No destination dispatcher");

  exit;

  }

  关于dispatcher 的选项配置

  

  3)重启 kamailio

  /etc/init.d/kamailio restart

  此时呼叫 可以查看kamailio的日志或者asterisk控制台 发现已经按照我们的配置按权重做了转发。

  Asterisk负载均衡用例图

  

  七、kamailio的HA

  此时发现虽然解决了asterisk的单点问题,但是没有解决kamailio的单点问题。我们选取keepalived解决kamailio的HA。Keepalived 引入需要vrrp(虚拟ip)的配合,这里我们指定192.168.1.4是192.168.1.5和192.168.1.6vrrp (这个需要在路由器端配置)。

  1)Keepalived(https://www.keepalived.org/)安装

  需要主备两台服务器 地址分别对应192.168.1.5和192.168.1.6。两台都得安装。

  2)Keepalived 配置

  两台机器的配置,基本一致只是一台是master一台是backup

  还需要修改 /etc/sysctl.conf文件输入

  net.ipv4.ip_nonlocal_bind = 1

  这条配置是允许linux的服务可以绑定虚拟ip,这里我们的kamailio需要绑定虚拟ip。

  3)启动keepalived

  service keepalived start

  两台都启动

  修改kamailio的配置文件 绑定虚拟ip

  listen=udp:192.168.1.4

  重启kamailio 这里已经是两台了 主备

  /etc/init.d/kamailio restart

  这是时候拨打虚拟ip就可以了

  4)HA的主备切换的检验

  针对kamailio 我们需要引入sipsak小软件,做sip探测比较合适

  安装sipsak

  yum install sipsak

  向kamailio发送探测 命令格式

  sipsak -s sip:s@192.168.1.4:5060

  根据返回值判断echo $?

  编写监测脚本 做逻辑处理

  这里大致说下脚本思路:利用sipsak 向kamailio发送探测命令,根据返回值是否为0判断kamailio是否存活,根据失败次数做keepalived的关闭这样就可以实现vrrp指向另一台机器。结合crontab 和shell脚本可以实现精细到每秒执行一次监测。

  Kamailio HA后的用例图

  

  八、回拨方案的解决

  现实中手机上并未启动voip电话,此时拨打用户是打不通的。为了解决这个问题我们设计了回拨方案,主要思路是当一方呼入电话时我们将这通电话hold起来,根据业务方式通知到另一方(比如push通知),当对方上线后我们放行这通电话就可以正常通话了,另一种方式是会议室方式,将呼入方先加入会议室,业务通知(同样可以push或者短信等)另一方,另一方收到通知后主动加入会议室,此时双方就可以通话啦。

  回拨方案的序列图

  

  九、NAT 问题简述

  在企业服务中通常公司都有防火墙和DNS服务器,我熟知的一般是bind服务,在对外网开放的时候,需要开放端口,同时需要做端口和ip转发。对应的外网地址转发到对应的内网地址上,这一点需要注意。在asterisk和kamailio中都有对NAT的支持,做对应的配置即可,其中的坑只能自己动手去踩坑,比较杂,这里就不做过多说明,如果公司实力强大,还可以搭建stun服务器,免费的一般不靠谱,这样既能解决端口问题又能解决NAT问题。

十、TLS和SRTP的支持

对于对外的服务来说,如果不想让别人看到你的数据和听到你的通话,需要在协议层引入TLS 语音层引入SRTP。tls和srtp都是需要单独安装的模块,在kamailio中编译安装的时候就需要指定tls.so的加入。Asterisk编译安装的时候也需要提前编译安装tls和srtp。至于证书没必要去购买 自签名的即可。Kamailio是可以单独配置rtpproxy的,所以这些服务都可以细分。

  十一、问题排查

  实际搭建过程中肯定会碰到各种各样的问题,如网络问题可以采用小工具netcat(https://www.jianshu.com/p/fa4eeac44e5c)进行排查,如果是分析sip协议哪步出的问题linux的 tcpdump是很好的工具,如果采用了tls协议,则有相对应的工具ssldump。最后推荐个非常实用的抓包软件wireshark,这款软件无论是分析sip协议还是丢包率,还是语音质量方面都是非常好用的。

  十二、总结

  如图是比较简单的voip接入呼叫中心的架构图,实际的应用项目中还有许多监控的事情,比如宕机的通知之类的事情这里和业务相关的就不多说了,真正搭建的过程中会遇到许许多的问题,在此只是一个小的总结,希望对大家有所帮助。

  

  欢迎留言交流或投稿,和我们一起分享知识。

  

  Qunar技术沙龙