简介

公司购买了一整套呼叫系统的设备,然后分别部署到了南宁公司和各个下级市的分公司,然后要求这套呼叫设备系统需要能接入ERP,可以方便的从ERP的点击客户联系电话或者输入电话号码就可以通过网页快速呼叫出去。

所以今天来总结一下呼叫系统开发实现的一些小细节。 (因为项目性质问题,这里代码里面的用户名和密码均修改为演示的)

系统分析

本身每套呼叫设备上都提供有一个C语言写的接口程序,对外提供WebService服务。

那么呼叫系统在进行一键呼出的时候,可以通过调用WebService服务来实现跟电话设备的交互。

因为南宁公司和4个下级市的分公司都分别处于不同的异地网络,所以每个公司都有一套呼叫的网关设备和服务器。

那么相当于是5套呼叫设备了,每套都在不同的地方,但是ERP却是统一使用一套ERP,所以存在一个ERP如何调用到分公司内网内的呼叫设备的问题?

关于这个的,我的解决方法是把呼叫模块独立成为一个服务程序,然后分别部署到各个公司的内部的一台服务器去,然后ERP的在线呼叫和呼叫弹屏的功能调用全部在走前端,然后走内网。

还是存在一个问题,就是WebService接口验证呢?怎么知道当前调用接口的员工是谁呢?接口验证的时候需要传递工号,密码,分机号,等信息过去,明文肯定不行了的?

那么就可以选择把员工的呼叫系统的信息进行使用公钥进行RSA加密,然后把加密后的字符串当做参数传递过去,在服务端再通过私钥进行RSA解密获取员工信息。

只是这样如何保证部署在分公司的服务的可用性呢? Shell定时检测,如果服务不可用,则发送短信提醒。

通话数据分析的需求也是包括南宁公司和下级市分公司,前面提到了,每个公司都有一台服务器保存通话记录,那么通话数据在四个分公司就是属于异地MySQL数据库了,从南宁公司远程连接到分公司内网的数据库这个稳定性无法保证这个问题怎么解决呢?

这个我想到了进行通话记录需要进行异地同步,这个可以配置MySQL主从同步嘛。比较方便。

但是最后呼叫设备系统的服务商告诉我们,不允许我们操作呼叫服务器 MySQL 数据库的配置。

汗,好吧。

那么由于呼叫系统的销售商所以MySQL 数据库同步可以配置主从同步的方法无法实现。

最终经过讨论和可行性分析,可以使用的解决方法是使用 PHP SWOOLE 来开启后台守护进程来执行异步任务,定时推送任务数据同步的任务给SWOOLE去执行。

来电/去电弹屏功能,这个功能公司要求每一通电话都需要有通话备注。所以原有的接口是只能通过AJAX一直请求呼叫服务的接口,有数据就返回数据的,但是这样就有Bug,就是当弹出一个信息的窗口后,如果员工没有及时备注,然后又来电/去电了,又弹出新的窗口,这样就导致了会弹出多个窗口,或者前面的弹窗丢失。

这个又是一个问题,那么这个问题该怎么解决呢?

为了解决这个问题,这里我们来使用了Redis的队列功能,PHP SWOOLE 开启后台守护进程,定时2s一次从呼叫服务器那边读取来电去电信息。

然后以队列的形式保存到Redis里面,保存规则以员工工号为前缀保存。进行弹屏推送的时候,再逐条出栈,最后我们再把AJAX 轮训的的请求方式更改为WebScoket主动推送的形式,这样就可以解决问题了。

使用到的PHP扩展

因为需要开启WebSocket,和后台进程进行异地定时数据同步,所以需要使用使用到 Swoole 扩展来实现异步任务。 编译安装 swoole ,开发阶段要记得编译的时候加上 --enable-swoole-debug 来开启调试模式,生产环节则去掉这个选项,如果要使用 WebSocket SSL 的话,我们还需要开启 OpenSSL 支持,加上 --enable-openssl

wget -c https://github.com/swoole/swoole-src/archive/v1.9.8.tar.gz && tar zxvf v1.9.8.tar.gz
cd swoole-src-1.9.8
/usr/local/php/bin/phpize
./configure --enable-swoole-debug --enable-openssl 
make 
sudo make install

编译安装成功后,修改php.ini加入

extension=swoole.so

最后通过 php -mphpinfo() 来查看是否成功加载了 swoole

数据库分表

呼叫系统中通话通话记录的数据表的数据量很大,呼叫系统是只要有电话(呼入/呼出)就往数据库写一条记录,然后通话结束后更新记录。

也就是说只要呼叫了,无论成功或者失败都需要生产记录,南宁公司每天的数据了量预计有 9K~2W 条,分公司每天预计有 2K ~ 5K 条记录,所以从数据库优化的角度出发,必须进行分表操作.

分表上通话记录表我们选用 MyISAM 引擎,按月份进行分表,每个月一张表,最后再使用MySQL 的 MERGE 存储引擎把一组 MyISAM 数据表当做一个逻辑单元来对待。

查询通话数据一般频繁查询是近3个月内的,所以我们再创建一张表,数据存储引擎使用的是 MRG_MYISAM 引擎(就是前面说的 MERGE 存储引擎),可以把近3个月的数据表联合然起来。这样就可以当做一张表来查询,这样可以应付大部分的查询。最后其他的查询时间超过3个月的再 union join 其他的表.

建表名称规则: 当月通话记录表名:call_log_info 非当月: 定时在每天凌晨检查是否是新的一个月,如果是新的一个月,把 call_log_info 表改名为 call_log_info_年月(如: call_log_1704) ,然后重新创建一个名称为call_log_info表保存当前新月份的通话记录

定时任务

检查是否到下一个月了
到新的一个月,就把上一个月的数据表改名,创建新表,修改关联表等等的操作
/usr/bin/php /home/wwwroot/sync_db/server.php home/transform/index

系统流程

根据流程图的模式,开发程序,连接WebService服务,调用接口,实现其他的各种业务逻辑。 end.