跳到正文

阿里云公网核心节点 (aliyun) 部署与更新手册 ​

该目录保存阿里云公网节点的所有组件部署配置、服务定义与更新操作说明。

重要说明:

  1. FreeSWITCH 软交换中心在阿里云上已经安装并稳定运行,无需再次安装或重新部署。
  2. 阿里云主要负责:
    • Web 前端静态站点更新:callflow-webpage、callout-webpage 两端 SPA 产物与文档站托管
    • 业务编排服务更新:callflow-esl 二进制、配置更新与 systemd 托管;
    • 公网入口与安全终结:Nginx (HTTPS/WSS 终结、反代、录音与静态托管);
    • 穿透与中继基础服务:FRPS (7000) 与 coTURN (3478 / 31000-31040)。

1. 目录结构与职责 ​

text
deploy/aliyun/
├── nginx/             # 公网 Nginx 反向代理、HTTPS SSL 终结与前端 SPA 静态托管
│   ├── ai-voice-public.conf
│   └── README.md      # server 块清单、反代规则、缓存与安全约定、排障速查
├── callflow-esl/      # FreeSWITCH Outbound ESL 业务编排服务
│   ├── callflow-esl.config.toml
│   └── callflow-esl.service
├── freeswitch/        # 核心 SIP 软交换中心配置参考树 (已有,无需重复部署)
│   ├── autoload_configs/  # modules / verto / local_stream / acl / switch 等模块级配置
│   ├── dialplan/          # default.xml:AI 业务 50xx、分机 10xx、会议 30xx、回音 9196
│   ├── directory/         # 分机 1000-1030
│   ├── sip_profiles/      # internal.xml:SIP 15321 (防运营商5060封锁)、WS 5066、WSS 7443
│   ├── tls/               # 样例证书,禁止直接复用
│   └── README.md          # 仓库侧变更清单与生产比对结论、上线约束
├── frp/               # FRP 反向代理穿透服务端 (FRPS)
│   ├── frps.toml
│   └── frps.service
├── coturn/            # WebRTC 5G 软电话 STUN/TURN 穿透服务
│   ├── turnserver.conf.example
│   ├── coturn.service
│   └── README.md
└── docs-site/         # 官方文档站点 (ai-voice.wangijun.com) Nginx 配置
    ├── nginx.conf
    ├── nginx-http-bootstrap.conf
    └── README.md

2. 服务与端口拓扑 ​

服务监听端口 / 地址部署路径说明
Nginx0.0.0.0:80, 443/etc/nginx/8 域名 HTTPS/WSS 终结、静态 SPA 托管与 API 反代(规则详见 nginx/README.md)
callflow-webpage前端静态资源/usr/app/webpage/callflow-webpage/dist/spa呼叫流程可视化前端 SPA (callflow.wangijun.com)
callout-webpage前端静态资源/usr/app/webpage/callout-webpage/dist/spa智能外呼与坐席管理前端 SPA(含「AI 策略中心」,callout.wangijun.com)
docs-site文档站静态资源/usr/app/ai-voice-docs/current平台技术文档站点 (ai-voice.wangijun.com)
callflow-esl127.0.0.1:9911 (ESL)
127.0.0.1:9912 (HTTP)
/usr/app/callflow-esl/Outbound ESL 呼叫流程控制服务
FreeSWITCH172.21.38.245:5066 (WS) / 7443 (WSS) / 8081+8082 (Verto)
12015 (inbound ESL), 30000-30199/UDP
/usr/local/freeswitch/已存在,软交换与 WebRTC 音视频交换中心;公网仅经 Nginx 443 暴露,详见第 3 节
FRPS0.0.0.0:7000
127.0.0.1:12000~12012
/usr/app/frp/接收 WSL 端反向穿透,仅绑定本地回环
coTURN0.0.0.0:3478 (UDP/TCP)
31000-31040/UDP
/etc/turnserver.confWebRTC NAT 穿透与媒体中继

3. WebRTC 音视频与会议背景音 ​

这两块能力都跑在已存在的 FreeSWITCH 上,不需要重装,但依赖的模块与配置分散在 freeswitch/autoload_configs/ 与 freeswitch/dialplan/,改动前先看清链路。

3.1 两条互不通用的 WebRTC 信令链路 ​

链路FreeSWITCH 端点Nginx 公网路径使用方
SIP over WSS(Sofia internal):5066 明文 WS、:7443 WSS(sip_profiles/internal.xml)fs.wangijun.com/ → https://172.21.38.245:7443坐席软电话(callout-webpage 的 use-sip-softphone,地址来自 callout-server agents.sipWsUrl)
Verto(mod_verto):8081 明文、:8082 加密(autoload_configs/verto.conf.xml)fs.wangijun.com/verto,以及工作台域名下的精确匹配 = /verto → http://172.21.38.245:8081callflow-webpage 的 /verto-videophone(use-verto-client)

两条链路的上游协议恰好相反且不能互换:Sofia 侧必须写 https://…:7443,Verto 侧必须写明文 http://…:8081(TLS 在 Nginx 终结,8082 的自签 wss.pem 不在公网路径上)。逐条规则与排障见 nginx/README.md 第 2.4 节。Verto 只承载信令,媒体仍走 external_rtp_ip 与 30000-30199/UDP,必要时经 coTURN 中继。

mod_av / mod_rtc / mod_verto 由 autoload_configs/modules.conf.xml 加载,缺一个视频页就只能起音频。 号码平面由 dialplan/default.xml 划分:

号码段去向说明
50xxsocket 127.0.0.1:9911 async full交给 callflow-esl 按 business_code / 被叫号码选业务;callout-server softphone.serviceNumber(当前 5020)必须落在此段内
10xxLocal_Extension → bridge user/<ext>@$${domain}分机互拨,同时设置 video_passthru、关键帧请求与 jitterbuffer_msec=60:120:20 等视频参数;分机 1000-1030 定义在 directory/default/
30xxconference $1@default会议室直拨
9196echo回音测试,排查单向音频/视频用

3.2 会议背景音 ​

链路是四段,任何一段缺失都只表现为“没声音”,不会报错:

  1. autoload_configs/modules.conf.xml 加载 mod_local_stream;
  2. autoload_configs/local_stream.conf.xml 声明 moh/8000 与 moh/16000 等保持音/背景音流 (对齐通用容器包 /data/docker_fs_server/ 标准定义,字段含义见 FreeSWITCH 模块配置手册 §6.2);
  3. 素材放到宿主机 /usr/local/freeswitch/share/freeswitch/sounds/music/{8000,16000}/(预置办公室底噪素材); 通用容器包 docker_fs_server.tar.gz 中已直接内置该素材(解压即用);在非容器化的独立宿主机上若需部署, 可直接取用包内素材并按采样率分目录存放;
  4. callflow-esl 的 backgroundAudio.profiles.office.streamUrl (local_stream://moh/16000)必须与第 2 步的 name 完全一致;实际是否播放由业务调用 ctx.conference.startBackgroundAudio() 决定,配置里的 enabled / volume 目前没有消费方。

💡 会议场景流式与整段 WAV 约束说明:当 tts.profiles.stream.playbackPrefix 为 "shout://"(当前阿里云部署现场配置)时, 会议场景 tts.use.conference 必须配置为 "wav"——因为 mod_shout 关闭时要 join 自己的 curl reader 线程(按 500ms 粒度让出), 实测阻塞 0.1~2.0 秒,而这次关闭跑在 mod_conference 唯一的 20ms 混音线程上,背景音与其他成员语音都会听得出中断。 若未来现场将流式前缀切换为 "audio_fork://"(原生 PCM16 流),则 conference 也可安全配置为 "stream"。


4. 前端与 ESL 部署/更新操作指南 ​

4.1 步骤一:构建前端产物与 ESL 二进制 ​

在本地(Windows / 开发机)根目录下执行构建:

bash
# 1. 构建两个 Quasar 前端 SPA 静态包 (默认 API 前缀为同域 /api)
bun run --cwd apps/callflow-webpage build
bun run --cwd apps/callout-webpage build

# 2. 构建 callflow-esl Linux x64 独立二进制
bun run --cwd apps/callflow-esl build

4.2 步骤二:上传并部署至阿里云服务器 ​

bash
# 1. 创建远程目标目录
ssh aliyun "mkdir -p /usr/app/webpage/{callflow-webpage,callout-webpage}/dist/spa /usr/app/callflow-esl"

# 2. 同步前端静态 SPA 产物(精准部署至 dist/spa 目录)
scp -r apps/callflow-webpage/dist/spa/* aliyun:/usr/app/webpage/callflow-webpage/dist/spa/
scp -r apps/callout-webpage/dist/spa/* aliyun:/usr/app/webpage/callout-webpage/dist/spa/

# 3. 同步 callflow-esl 二进制与配置文件
scp apps/callflow-esl/dist/callflow-esl aliyun:/usr/app/callflow-esl/
scp deploy/aliyun/callflow-esl/callflow-esl.config.toml aliyun:/usr/app/callflow-esl/config.toml

4.3 步骤三:权限设置与服务重启 ​

登录阿里云执行服务重载与生效:

bash
ssh aliyun

# 1. 设置可执行权限与目录属主(必须保证 a+rX 权限,避免 Nginx 404)
chmod +x /usr/app/callflow-esl/callflow-esl
chmod -R a+rX /usr/app/webpage/
chown -R aivoice:aivoice /usr/app/callflow-esl /usr/app/webpage

# 2. 重启 callflow-esl 服务
sudo systemctl restart callflow-esl
sudo systemctl status callflow-esl

# 3. 检查 Nginx 配置并平滑重载
sudo nginx -t && sudo systemctl reload nginx

5. 验证与排障 ​

bash
# 1. 验证 callflow-esl 监听状态 (9911 与 9912)
ss -tulpn | grep -E '9911|9912'

# 2. 验证 ESL HTTP 接口健康状态
curl -H "Token: esl-0x21" http://127.0.0.1:9912/health

# 3. 验证 FreeSWITCH Inbound ESL 状态 (已有 12015 端口)
nc -zv 127.0.0.1 12015

# 4. 验证公网 HTTPS / WSS 域名解析与证书状态
curl -Iv https://callflow.wangijun.com/
curl -Iv https://callout.wangijun.com/
curl -Iv https://ai-voice.wangijun.com/

# 5. 验证两条 WebRTC 信令端点在监听 (Sofia WS/WSS 与 Verto 明文口)
ss -tulpn | grep -E '5066|7443|8081'

# 6. 验证会议背景音模块与素材
fs_cli -x "module_exists mod_local_stream"   # 期望 true
fs_cli -x "local_stream show"                # 期望列出 moh/8000 与 moh/16000 等流
ls /usr/local/freeswitch/share/freeswitch/sounds/music/16000/

文档与代码在同一仓库维护,现有 Markdown 是唯一内容源。