FreeSWITCH HA
1、环境说明
实验环境:Ubuntu 16.04 + Heartbeat_3.0.6-2+FreeSWITCH _1.10.5+nginx_1.10.3
Heartbeat 下载地址:https://launchpad.net/ubuntu/xenial/amd64/heartbeat/1:3.0.6-2
docker下载地址:https://packages.ubuntu.com/xenial-updates/docker.io
nginx 下载地址:https://packages.ubuntu.com/xenial/amd64/nginx-core
上述工具可以直接下载源码进行编译,也可以直接下载二进制文件。
2、结点划分
pbx1 pbx1.ha.com 192.168.6.180 pbx2 pbx2.ha.com 192.168.6.182 vip: pbx1.ha.com 192.168.6.186
3、修改主机名
节点192.168.6.180 192.168.6.182分别改名为pbx1 pbx2
sudo vim /etc/hostname #输入pbx1 pbx1
配置节点pbx1中/etc/hosts文件
127.0.0.1 pbx1 127.0.0.1 localhost 192.168.6.180 pbx1 192.168.6.182 pbx2
配置节点pbx2中/etc/hosts文件
127.0.0.1 pbx2 127.0.0.1 localhost 192.168.6.180 pbx1 192.168.6.182 pbx2
如此,及时实现通过主机名互访:
ssh user@pbx1 # or ssh user@pbx2
4、安装Heartbeat
分别在节点pbx1和pbx2安装heartbeat。
cd heartbeat_3.0.6/ sudo dpkg -i gawk_4.1.3+dfsg-0.1_amd64.deb sudo dpkg -i *.deb
5、安装nginx
分别在pbx1 安装nginx用于测试。
sudo dpkg -i nginx-common_1.10.3-0ubuntu0.16.04.5_all.deb sudo dpkg -i nginx-core_1.10.3-0ubuntu0.16.04.5_amd64.deb
将/var/www/html/下文件index.nginx-debian.html更名为index.html,内容修改为:
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to pbx1 nginx!</h1> <p><em>Thank you for using nginx.</em></p> </body> </html>
打开页面显示如下内容,表示部署成功:
将nginx安装文件拷贝至pbx2节点
scp -r /home/fsdir/nginx_1.10.3/ user@pbx2:/home/fsdir/
安装相同的方式部署pbx2结点的nginx。
测试成功后,执行下列命令(关闭服务和关闭开机启动服务):
sudo systemctl stop nginx.service sudo systemctl disable nginx.service
7、配置heartbeat
1)在pbx1结点做如下配置
实现数字签名登录。
首先在本机生成公、私钥文件。
ssh-keygen -q -t rsa -N '' -f ~/.ssh/id_rsa
复制公钥到对端机器 .ssh 目录
ssh-copy-id user@192.168.6.182
are/doc/heartbeat/目录。解压ha.cf.gz和hareasources.gz文件
sudo gzip -d ha.cf.gz
sudo gzip -d haresources.gz
并将ha.cf、authkeys和haresources文件拷贝至/etc/ha.d目录下。
并将authkeys权限更改为600。
sudo chom 600 ./authkeys
配置ha.cf文件
debugfile /var/log/ha-debug #表示调试的日志文件 一般测试建议开启 logfile /var/log/ha-log #表示系统的的日志文件路径 logfacility local0 #表示使用系统日志与上面只能开启一个 keepalive 2 #主备之间的心跳间隔时间单位:s deadtime 30 #表示如果连接对方30s还无法连接,表示节点死亡需要考虑vip转移 warntime 10 #表示10s时间未收到心跳时发出警告日志 initdead 120 #有时机器启动后需要一段时间网卡才能正常工作 需要预留一定的时间后,再开始判断心跳检测 udpport 694 #多播的udp端口 ucast enp1s0 192.168.6.180 #设置单播心跳,设置本地网卡和对方的ip地址,此处使用单播 auto_failback on #表示如果主机停止后,从机接管设置为on当主机从新启动后,主机立即接管vip off从机不会释放vip给主机 node pbx1 #配置主从的节点信息,要与uname -n保持一致 node pbx2 ping 192.168.6.1
配置authkeys文件
auth 2 #表示使用id为2的验证 下边需要定义一个2的验证算法 2 sha1 1a2b3c #ID 2的验证加密为shal,并添加密码
创建热备资源
ln -s /etc/init.d/nginx /etc/ha.d/resource.d/nginx
配置haresources配置文件
pbx1 192.168.6.186 nignx
最后重启hearbeat服务即可。
2)pbx2配置
与pbx1配置相同,ha.cf文件中 ucast enp1s0 192.168.6.180 地址改为192.168.6.182,haresources中pbx1 192.168.6.186 nignx 改为 pbx2 192.168.6.186 nignx即可。
8、测试
在浏览器输入192.168.6.186,显示:
关闭pbx1后,刷新浏览器显示:
开启pbx1后,再次显示:
说明Heartbeat HA配置成功。
9、FreeSWITCH安装
先安装docker,然后docker中部署FreeSWITCH镜像。过程略。
注意,非docker部署FS时需要配置开机启动服务
代码如下(debian环境)
# Stop dance for fs # ======================= # # ExecStop sends SIGSTOP (graceful stop) to the fs process. # If, after 5s (--retry QUIT/5) nginx is still running, systemd takes control # and sends SIGTERM (fast shutdown) to the main process. # After another 5s (TimeoutStopSec=5), and if fs is alive, systemd sends # SIGKILL to all the remaining processes in the process group (KillMode=mixed). # # [Unit] Description=freeswitch server After=network.target [Service] User=root ExecStart=/usr/local/freeswitch/bin/freeswitch -nc -nf ExecStop=/bin/kill -9 $MAINPID TimeoutStopSec=5 [Install] WantedBy=multi-user.target
10、postgresql部署
安装数据库:
dpkt -i *.deb
安装完毕后,系统会创建一个数据库超级用户postgres,密码为空。
sudo -i -u postgres
使用如下命令进入postgres,输出如下信息,则说明安装成功。
~$ psql psql (9.5.17) Type "help" for help. postgres=#
postgreSQL 安装完成后默认是已经启动的,但是也可以通过下面的方式来手动启动服务。
sudo /etc/init.d/postgresql start # 开启 sudo /etc/init.d/postgresql stop # 关闭 sudo /etc/init.d/postgresql restart # 重启
11、FreeSWITCH配置
配置freeswitch数据库。
1)postgresql直接访问数据库
修改postgres数据库用户的密码为123456。
#其中,sudo -u postgres 是使用postgres 用户登录的意思 #PostgreSQL数据默认会创建一个postgres的数据库用户作为数据库的管理员,密码是随机的 sudo -u postgres psql postgres=# ALTER USER postgres WITH PASSWORD '123456';
退出PostgreSQL psql客户端
postgres=# \q
修改ubuntu操作系统的postgres用户的密码(密码要与数据库用户postgres的密码相同)
sudo passwd -d postgres sudo -u postgres passwd
修改PostgresSQL数据库配置实现远程访问。
vim /etc/postgresql/9.5/main/postgresql.conf #监听任何地址访问,修改连接权限。 #listen_addresses = 'localhost' 改为 listen_addresses = '*' #启用密码验证 #password_encryption = on 改为 password_encryption = on vim /etc/postgresql/9.4/main/pg_hba.conf #在文档末尾加上以下内容 host all all 0.0.0.0 0.0.0.0 md5
重启服务。
etc/init.d/postgresql restart
5433端口的防火墙设置
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5432 -j ACCEPT
登录postgre SQL数据库
psql -U postgres -h 127.0.0.1
创建新用户freeswitch
,但不给建数据库的权限
postgres=# create user "freeswitch" with password 'freeswitch' nocreatedb;
建立数据库,并指定所有者
postgres=#create database "freeswitch" with owner = "freeswitch";
需要修改的配置文件
switch.conf.xml //核心表 cdr_pg_csv.conf.xml //通话记录 db.conf.xml //核心表 voicemail.conf.xml //留言相关的表 internal.xml // 内呼表 external.xml // 外呼表 fifo.conf.xml //fifo相关的表 callcenter.conf.xml //callcenter程序相关的表
switch.conf.xml
<param name="core-db-dsn" value="pgsql://host=localhost dbname=freeswitch user=freeswitch password='freeswitch' options='-c client_min_messages=NOTICE' application_name='freeswitch'" />
<param name="core-recovery-db-dsn" value="pgsql://hostaddr=192.168.6.16 dbname=freeswitch user=freeswitch password='freeswitch' options='-c client_min_messages=NOTICE'" />
cdr_pg_csv.conf.xml
<param name="db-info" value="host=localhost user=freeswitch password=nopassword dbname=freeswitch connect_timeout=10" /> <param name="db-table" value="xml_cdr"/>
在vars.xml中加入如下配置:
<X-PRE-PROCESS cmd="set" data="dsn=pgsql://hostaddr=127.0.0.1 dbname=freeswitch user=freeswitch password='password' options='-c client_min_messages=NOTICE' application_name='freeswitch'" /> <X-PRE-PROCESS cmd="set" data="dsn_callcenter=pgsql://hostaddr=127.0.0.1 dbname=freeswitch user=freeswitch password='password' options='-c client_min_messages=NOTICE' application_name='freeswitch'" />
配置db.conf.xml、voicemail.conf.xml、external.xml、internal.xml 、fifo.conf.xml、callcenter.conf.xml
<param name="odbc-dsn" value="$${dsn}">
【附】xml_cdr建表sql及cdr_pg_csv.conf.xml 字段设置
CREATE TABLE "public"."xml_cdr" (
"uuid" uuid NOT NULL,
"domain_uuid" uuid,
"extension_uuid" uuid,
"domain_name" text COLLATE "default",
"accountcode" text COLLATE "default",
"direction" text COLLATE "default",
"default_language" text COLLATE "default",
"context" text COLLATE "default",
"xml_cd" text COLLATE "default",
"json" jsonb,
"caller_id_name" text COLLATE "default",
"caller_id_number" text COLLATE "default",
"source_number" text COLLATE "default",
"destination_number" text COLLATE "default",
"start_epoch" numeric,
"start_stamp" timestamp(6),
"answer_stamp" timestamp(6),
"answer_epoch" numeric,
"end_epoch" numeric,
"end_stamp" text COLLATE "default",
"duration" numeric,
"mduration" numeric,
"billsec" numeric,
"billmsec" numeric,
"bridge_uuid" text COLLATE "default",
"read_codec" text COLLATE "default",
"read_rate" text COLLATE "default",
"write_codec" text COLLATE "default",
"write_rate" text COLLATE "default",
"remote_media_ip" text COLLATE "default",
"network_addr" text COLLATE "default",
"recording_file" text COLLATE "default",
"leg" char(1) COLLATE "default",
"pdd_ms" numeric,
"rtp_audio_in_mos" numeric,
"last_app" text COLLATE "default",
"last_arg" text COLLATE "default",
"cc_side" text COLLATE "default",
"cc_member_uuid" uuid,
"cc_queue_joined_epoch" text COLLATE "default",
"cc_queue" text COLLATE "default",
"cc_member_session_uuid" uuid,
"cc_agent" text COLLATE "default",
"cc_agent_type" text COLLATE "default",
"waitsec" numeric,
"conference_name" text COLLATE "default",
"conference_uuid" uuid,
"conference_member_id" text COLLATE "default",
"digits_dialed" text COLLATE "default",
"pin_number" text COLLATE "default",
"hangup_cause" text COLLATE "default",
"hangup_cause_q850" numeric,
"sip_hangup_disposition" text COLLATE "default",
CONSTRAINT "xml_cdr_pkey" PRIMARY KEY ("uuid")
)
WITH (OIDS=FALSE)
;
ALTER TABLE "public"."xml_cdr" OWNER TO "freeswitch";
2)ODBC方式访问数据库
odbc驱动自行安装。
odbcinst.int
[PostgreSQL ANSI] Description=PostgreSQL ODBC driver (ANSI version) Driver=/usr/lib/x86_64-linux-gnu/odbc/psqlodbca.so Setup=/usr/lib/x86_64-linux-gnu/odbc/libodbcpsqlS.so Debug=0 CommLog=1 UsageCount=1 [PostgreSQL Unicode] Description=PostgreSQL ODBC driver (Unicode version) Driver=/usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so Setup=/usr/lib/x86_64-linux-gnu/odbc/libodbcpsqlS.so Debug=0 CommLog=1 UsageCount=1
odbc.ini
[freeswitch] Description = Postgres-freeswitch Driver = /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so Servername = 192.168.6.180 port = 5433 Username = freeswitch Password = freeswitch Database = freeswitch ReadOnly = no
配置完成之后,输入 isql freeswitch -v 显示"Connected!"表示连接数据库成功。如下图所示:
switch.conf.xml
<param name="core-db-dsn" value="odbc://freeswitch::" />
db.conf.xml、fifo.conf.xml、callcenter.conf.xml、external.xml、internal.xml 、voicemail.conf.xml
<param name="odbc-dsn" value="odbc://freeswitch::"/>
3)允许FreeSWITCH绑定非本地IP
在/etc/sysctl.conf文件尾加入
net.ipv4.ip_nonlocal_bind=1
重启网络
/etc/init.d/networking restart
运行命令 sysctl -p 可看到输出
net.ipv4.ip_nonlocal_bind = 1
4)freeeswitch配置
在/etc/network/interfaces加入如下内容:
iface enp1s0:0 inet static address 192.168.6.186 netmask 255.255.255.0
进入docker容器中将FreeSWITCH的sip监听地址设为vip(192.168.6.186)。
<param name="rtp-ip" value="192.168.6.186"/> <param name="sip-ip" value="192.168.6.186"/> <param name="presence-hosts" value="192.168.6.186"/> <param name="ext-rtp-ip" value="192.168.6.186"/> <param name="ext-sip-ip" value="192.168.6.186"/>
配置完后,可以通过grep查询数据配置是否正确。
将vars.xml中,将local_ip_v4值改为192.168.6.186。由
<X-PRE-PROCESS cmd="set" data="domain=$${local_ip_v4}"/>
改为
<X-PRE-PROCESS cmd="set" data="domain=192.168.6.186"/>
将
<X-PRE-PROCESS cmd="set" data="bind_server_ip=auto"/>
改为
<X-PRE-PROCESS cmd="set" data="bind_server_ip=192.168.6.186"/>
在external.xml和internal.xml文件中加入如下配置,将运行中所以的通话保存到数据库。
<param name="track-calls" value="true"/>
在freeswitch.xml中添加配置,使freeswitch启动时自动恢复所有通话。
<X-PRE-PROCESS cmd="set" data="api_on_startup=sofia recover"/>
统一freeswitch实例名称,在节点pbx1和pbx2上将switch.con.xml中switchname修改为pbx。
<param name="switchname" value="pbx"/>
配置完后,reboot系统,打一个电话则可以在recovery表中看到当前正在通话的电话信息。