FreeSWITCH通话记录接口:CDR模块设计与优化实践

FreeSWITCH通话记录接口:CDR模块设计与优化实践

一、CDR模块基础架构解析

通话记录(Call Detail Record, CDR)是VoIP系统的核心组件,用于记录每次通话的元数据,包括主被叫号码、通话时长、计费信息等。在FreeSWITCH中,CDR模块通过事件订阅机制捕获通话生命周期事件,并将其转换为结构化数据。

1.1 事件驱动架构

FreeSWITCH采用事件驱动模型,CDR生成依赖以下关键事件:

  • CHANNEL_CREATE:通话建立时触发
  • CHANNEL_ANSWER:被叫应答时触发
  • CHANNEL_DESTROY:通话结束时触发
  • DTMF:按键事件(可选记录)

模块通过mod_event_socket或内置mod_cdr监听这些事件,将原始事件数据映射为CDR字段。例如:

  1. <!-- FreeSWITCH配置示例:启用CDR模块 -->
  2. <configuration name="cdr.conf" description="CDR Configuration">
  3. <settings>
  4. <param name="csv-dir" value="/var/log/freeswitch/cdr"/>
  5. <param name="csv-format" value="csv"/>
  6. <param name="pg-csv" value="true"/> <!-- 启用PostgreSQL存储 -->
  7. </settings>
  8. </configuration>

1.2 核心数据结构

CDR字段通常包含以下维度:
| 字段名 | 类型 | 描述 |
|————————|——————|—————————————|
| uuid | STRING | 通话唯一标识符 |
| caller_id | STRING | 主叫号码 |
| destination | STRING | 被叫号码 |
| start_epoch | INTEGER | 通话开始时间(Unix时间戳)|
| answer_epoch | INTEGER | 被叫应答时间 |
| end_epoch | INTEGER | 通话结束时间 |
| duration | INTEGER | 通话总时长(秒) |
| billsec | INTEGER | 计费时长(秒) |
| hangup_cause | STRING | 挂断原因 |

二、CDR接口实现方案

FreeSWITCH支持多种CDR输出方式,开发者可根据业务需求选择适配方案。

2.1 本地文件存储

方案特点:简单易用,适合小型系统
实现步骤

  1. 修改cdr.conf配置CSV输出路径
  2. 设置定时任务归档日志文件
  3. 通过脚本解析CSV进行二次处理

示例代码(Python解析CSV):

  1. import csv
  2. from datetime import datetime
  3. def parse_cdr(file_path):
  4. with open(file_path, 'r') as f:
  5. reader = csv.DictReader(f)
  6. for row in reader:
  7. start_time = datetime.fromtimestamp(int(row['start_epoch']))
  8. duration = int(row['duration'])
  9. print(f"通话时间: {start_time}, 时长: {duration}秒")

2.2 数据库集成

方案特点:实时性强,支持复杂查询
主流数据库适配

  • PostgreSQL:通过mod_db模块直接写入
    1. <param name="db-url" value="postgres://user:pass@localhost/cdrdb"/>
  • MySQL:需配置ODBC驱动
  • 时序数据库:适合大规模CDR分析(如InfluxDB)

性能优化建议

  • 批量插入替代单条提交
  • uuidstart_epoch建立复合索引
  • 分表策略(按日期或客户ID)

2.3 消息队列中转

适用场景:高并发、解耦存储与处理
实现流程

  1. 配置mod_erlang_eventmod_kafka
  2. 定义消息格式(JSON/Protobuf)
  3. 消费者服务处理CDR数据

Kafka生产者配置示例

  1. <configuration name="kafka.conf">
  2. <producers>
  3. <producer name="cdr_producer">
  4. <param name="brokers" value="kafka1:9092,kafka2:9092"/>
  5. <param name="topic" value="freeswitch_cdr"/>
  6. </producer>
  7. </producers>
  8. </configuration>

三、高级功能实现

3.1 自定义字段扩展

通过cdr_custom变量注入业务数据:

  1. <action application="set" data="cdr_custom=${call_type}_${campaign_id}"/>

cdr.conf中映射:

  1. <param name="custom-fields" value="call_type,campaign_id"/>

3.2 实时计费引擎

结合Lua脚本实现动态费率计算:

  1. session:setVariable("billsec", duration)
  2. local rate = 0.02 -- 每秒费率
  3. local cost = rate * duration
  4. session:execute("set", "cdr_cost=" .. cost)

3.3 多租户隔离

通过domain变量实现租户级CDR分离:

  1. <param name="csv-filename" value="${domain}_cdr_${strftime(%Y%m%d)}.csv"/>

四、性能优化与故障排查

4.1 瓶颈分析与调优

常见问题

  • 高并发写入延迟:数据库连接池不足
  • 磁盘I/O过载:CSV文件未做轮转
  • 内存泄漏:未释放的CDR事件句柄

优化方案

  • 启用异步写入模式
  • 增加mod_cdrbuffer-size参数
  • 对历史CDR实施冷热数据分离

4.2 监控指标

关键监控项:
| 指标名 | 阈值 | 告警策略 |
|—————————|——————|————————————|
| CDR生成延迟 | <500ms | 超过1s触发告警 |
| 数据库写入TPS | >200/秒 | 下降50%时告警 |
| 磁盘空间使用率 | <85% | 超过90%自动清理旧数据 |

五、安全与合规实践

5.1 数据脱敏处理

通话记录涉及用户隐私,需实施:

  • 主被叫号码部分隐藏(如138****1234
  • 录音文件加密存储
  • 访问权限分级控制

5.2 合规性要求

  • 符合GDPR、等保2.0等法规
  • 保留CDR数据不少于6个月
  • 提供用户数据查询/删除接口

六、部署架构建议

6.1 单机部署方案

适用场景:中小型呼叫中心
架构图

  1. FreeSWITCH mod_cdr(CSV) Logrotate 分析服务

6.2 分布式集群方案

适用场景:大型云呼叫中心
架构组件

  • Zookeeper:协调多节点CDR收集
  • Kafka集群:缓冲高并发CDR
  • Flink流处理:实时计算KPI
  • ClickHouse:OLAP分析

七、未来演进方向

  1. AI驱动分析:通过CDR数据训练通话质量预测模型
  2. 区块链存证:确保CDR不可篡改性
  3. 边缘计算:在网关侧预处理CDR减少核心网压力

通过系统化的CDR接口设计,企业可构建从基础通话记录到智能运营分析的完整闭环。实际部署时,建议结合业务规模选择渐进式技术演进路径,初期优先保障数据完整性与系统稳定性,再逐步叠加高级分析功能。