☰
FreeSWITCH呼入呼出路由配置详解:从Dialplan到网关排错
2026/9/30 7:43:00 网站建设 项目流程

简介:针对Freeswitch呼入呼出路由配置与SIP中继设置的实战参考,面向VoIP运维、通信开发及网络工程师。文档以FreeSwitch V1.2.7为基础,从系统启动与消息分发入手,逐步展开呼入路由、外呼策略、对等中继模式下SIP中继地址与端口的配置,同时覆盖拨号计划、网关接入、PSTN中继、TLS安全、负载均衡和错误恢复等关键环节。内容预览中可以看到完整的目录结构,从核心架构、程序启动、消息分发到mod_sofia模块的组成与启动均有章节说明,便于按模块深入查阅。资源包为1个doc文档,整体约221KB,轻量但信息密度较高。已有6448人学习,适合需要快速理解Freeswitch路由机制并落地SIP中继配置的读者,也可作为日常排错与二次开发的参考。

1. 呼入呼出路由配置到底是什么问题:先看懂三个"路由黑洞"场景

一个场景:电话拨进公司总机,转分机号,一直响铃没人接,最后掉进语音信箱;另一个:分机拨 0 外呼,电话里直接说呼叫不能完成;还有一条:两条外线网关都配好了,呼出却永远走第一条。三个现象背后是同一个根因—— freeswitch 呼入呼出路由配置详解 这套链路没吃透。这里说的路由不是网络层静态路由,而是 FreeSWITCH 拨号计划(dialplan)为每个通话找出口的过程。下面用可复现的 XML 配置把呼入、呼出、网关选择和排错串起来,适合刚拿到 FreeSWITCH 就被拉去配语音的运维,也适合已配好基本分机但被外线折腾的人。读完你能自己造一张跑通呼入分机和呼出外线的 dialplan,并能定位失败原因。

2. 路由配置的根:dialplan 的结构与选型理由

2.1 dialplan 不是路由表,而是一段带正则的 XML 解释器

第一次接触 FreeSWITCH 的人,最容易把 dialplan 想象成一张和ip route差不多的表:号码前缀对网关,查表转发。实际上 dialplan 是一段逐条执行的 XML 规则,执行顺序是自上而下、逐条匹配,命中后执行完就停(除非显式要求继续匹配)。我把 FreeSWITCH 的拨号计划类比成网络静态路由和 iptables 的某种合体:匹配字段、正则表达式、动作串在一起,但没有任何动态路由协议在背后自动收敛——你不需要(也不能)指望它像 OSPF 或 RIP 那样发现新网关后自动学习路由,电话网号码和网关之间的关系本来就需要人工维护,静态化反而是优点。

dialplan 的结构分三层:

元素作用对应关系
context呼叫上下文,相当于路由实例呼入用 public,分机内部用 default 很常见
extension路由条目可以理解成一条路由规则
condition匹配条件相当于路由前缀匹配
action / anti-action命中后的动作 / 未命中后的动作对应执行操作

每个 extension 至少要有一个 condition,condition 里用field指定要匹配的呼叫变量,用expression写正则。常见的 field 是destination_number(被叫号码)和caller_id_number(主叫号码)。整个 XML 文件默认放在conf/dialplan/下,一个新的 context 可以被多个拨号计划文件共用;我一般习惯把呼入、呼出、内部互打拆成三个 XML 文件,方便定位问题,而不是把所有 extension 堆在同一个 default.xml 里。

从跨平台的角度说,无论你在 Linux 上从源码编译安装,还是直接拿 freeswitch安装win 的安装包装好,dialplan 的 XML 语法是一致的,差别只在 conf 目录路径和编码细节。Windows 上尤其注意文件的编码,后文避坑章会专门说。

2.2 为什么 FreeSWITCH 不用「动态路由协议」那一套

先说结论:电话路由不需要动态收敛,所以 FreeSWITCH 选择了静态 XML 解释器模式。电话路由的"网段"是号码前缀,"下一跳"是网关(gateway),但前缀和网关的映射变化频率很低,而且一条路由配错只影响一类呼叫,不会像网络环路一样把整个业务打挂。FreeSWITCH 官方不提供像 OSPF 那样的自动选路模块,社区里常见做法就是靠条件判断和 bridge 顺序实现多网关兜底。

这带来一个选型上的好处:路由逻辑可以被版本化管理,改错了随时回滚,不会因为一个错误路由扩散波及全盘。但也带来一个代价:所有分支都要自己写。比如呼入时间路由、周末路由、节假日路由,全部要在 dialplan 里用 condition 堆出来。这与 ensp 里做静态路由配置实验的思路很像——把每条路径显式声明出来,而不是依赖协议自动收敛。现实中我看到不少团队会额外加一套配置生成系统,用模板把 dialplan 生成出来,也没有引入动态路由协议,说明静态方案在语音网关这个场景里是够用的。

2.3 最小可用的 dialplan 模板:看懂 condition / action / anti-action

下面是最小可用的一个呼入分机路由,它把拨 1000 的呼叫桥接给分机 1000。把这个 context 放进conf/dialplan/default.xml,或者在主配置里 include 一个新文件。

<include> <context name="default"> <extension name="internal-call-to-1000"> <condition field="destination_number" expression="^1000$"> <action application="bridge" data="user/1000"/> </condition> </extension> </context> </include>

逻辑说明:当呼叫进入 default 这个 context 时,通道变量destination_number会被拿去和^1000$做整串匹配;命中了就执行bridge,把呼叫接续到user/1000。bridge是 FreeSWITCH 里最重要的路由动作,它不只是"转接",而是把当前通话通道和一个新通道连起来,新通道可以是分机、IVR、队列或网关。

参数说明里有两个点值得展开。第一,正则里的^和$不是可选的,省略后会出现"10001 也命中了 1000 路由"的意外;第二,user/1000这个目标是 FreeSWITCH 内置的呼叫定位语法,它根据当前拨号计划查找到注册的分机 1000,比起直接写sofia/internal/1000@domain这种形式更省心。如果 condition 没命中,且你写了anti-action,就会执行这里的内容,一般用来放提示音或拒接日志。

我再给一个带 anti-action 的写法,保证未匹配时能留下可查痕迹:

<extension name="catch-all-missed"> <condition field="destination_number" expression="^(\d+)$"> <anti-action application="log" data="WARNING 未匹配号码 ${destination_number} 来源 ${caller_id_number}"/> <anti-action application="hangup"/> </condition> </extension>

逻辑说明:anti-action在 condition 的正则匹配失败时执行。上面这段把未匹配的可疑呼叫记进日志然后挂断,避免呼叫在 FreeSWITCH 里无线空转。这里有一个常见误区:anti-action是跟着 condition 走的,不是跟着 extension 走的,一个 extension 里多个 condition 时,每个 condition 都能有自己的 anti-action。

这里还有一个决定路由行为的隐藏开关:continue。extension 标签上如果写了continue="true",命中执行完后不会停,而是继续往下匹配后面的 extension。这对做补充计费、逐个网关尝试很有用。默认情况不写 continue 时,路由是"首次命中即终态"。我通常只在多网关轮询和呼叫权限审计两块用 continue,其他地方尽量少开,开着开着就会迷路。

3. 呼入路由怎么配:从分机直达、IVR 到时间分支

3.1 呼入路由的最小闭环:把来电转给分机 1000

先明确呼入和呼出的分界线。呼入是从外部线路(PSTN/中继)打进 FreeSWITCH,先落在 SIP profile,然后进入 dialplan 的某个 context。大部分默认配置文件里,外部呼叫会进入publiccontext,而public的权限比default小得多。所以配置呼入路由时,第一步不是写 bridge,而是确认来电落在哪个 context。

我的常见做法是:在conf/dialplan/public.xml里写一条只处理指定被叫号码的路由。假设总机被叫是86660000,来电拨这个号码后转到分机 1000:

<include> <context name="public"> <extension name="inbound-to-ext-1000"> <condition field="destination_number" expression="^86660000$"> <action application="answer"/> <action application="sleep" data="500"/> <action application="bridge" data="user/1000"/> </condition> </extension> </context> </include>

逻辑说明:第一步answer先应答,让线路进入通话状态;第二步sleep 500给 0.5 秒缓冲,避免一端刚应答另一端立即接续导致极端情况下首包丢失;第三步bridge把呼叫转给分机。这三步是呼入路由的常见起手式,先应答再转接,可以让后面的动作更顺畅。

参数说明:data="user/1000"依赖分机号存在且在 default context 里可被发现。如果分机注册不在本机(比如用了外部 SIP 终端),就要把 bridge 目标改成sofia/internal/1000@你的域名或IP。domain 配错是呼入转分机失败的高发点,因为 FreeSWITCH 会根据 domain 查找分机归属。

3.2 按主叫/被叫分流到 IVR 或队列:两个常用动作

呼入路由很少只做"转分机",更多是按主叫或被叫去分流。两个高频动作是play_and_get_digits和callcenter。前者做 IVR 交互,后者把呼叫送进排队队列。

<extension name="inbound-ivr"> <condition field="destination_number" expression="^86660000$"> <action application="answer"/> <action application="play_and_get_digits" data="3 8 3 7000 ${ivr_choice} /usr/local/freeswitch/sounds/ivr-menu.wav /usr/local/freeswitch/sounds/ivr-invalid.wav ivr 5 3000"/> <action application="set" data="dest_ext=${ivr_choice}"/> <action application="bridge" data="user/${dest_ext}"/> </condition> </extension>

逻辑说明:play_and_get_digits是 FreeSWITCH 的按键收集动作,参数从左到右分别是:最多收 3 位、最大静音 8 秒、最多重试 3 次、超时后默认值 7000(按 7)、存结果的变量名${ivr_choice}、提示音文件、无效输入提示音、音频模式、识别超时、整体等待。收集完成后,set把结果存成新变量dest_ext,最后bridge到对应分机。这个写法可以支撑一个很简短的 IVR 菜单。

参数说明:play_and_get_digits的参数位次不能记错,错一位会出现"提示音没播完就收键"或"怎么按都不响应"的现象。音频路径建议写绝对路径,且最好用 wav 格式,MP3 在某些编译版本上需要额外模块支持,踩过坑的人大多会改用 wav。

把呼叫送进队列,用的是callcenter应用。它依赖mod_callcenter,队列定义在conf/autoload_configs/callcenter.conf.xml里:

<extension name="inbound-callcenter"> <condition field="destination_number" expression="^86660000$"> <action application="answer"/> <action application="callcenter" data="support_queue"/> </condition> </extension>

逻辑说明:callcenter的第一个参数是队列名,这里写的support_queue必须在 callcenter.conf.xml 的<queues>里定义好,否则路由会报 "queue not found"。队列里可以配坐席策略(轮流、最长空闲、最少通话)和超时溢出策略。这里我只给到 dialplan 侧的动作,队列策略本身仍然留在 callcenter.conf.xml 中,不要在 dialplan 里改坐席分配。

3.3 呼入的时间路由:上班时间进队列,下班时间进语音信箱

呼入路由的另一个常见维度是时间。FreeSWITCH 的 condition 原生支持hour、wday、mday等字段,可以按星期和小时做分支。这里的思路是"先匹配时间段,再匹配号码",而不是在同一个 condition 里堆两个维度。

<extension name="inbound-business-hours"> <condition field="destination_number" expression="^86660000$" hour="08:00-18:00" wday="1-5"> <action application="answer"/> <action application="callcenter" data="support_queue"/> </condition> </extension> <extension name="inbound-after-hours"> <condition field="destination_number" expression="^86660000$"> <action application="answer"/> <action application="play_and_get_digits" data="1 6 2 9 ${vm_option} /usr/local/freeswitch/sounds/afterhours.wav 7000 * 5 3000"/> <action application="bridge" data="user/1000"/> </condition> </extension>

逻辑说明:第一个 extension 的 condition 同时带了hour和wday属性,只有周一至周五(1-5)且 08:00 到 18:00 之间才命中;第二个 extension 是兜底,所有未命中第一个条件的 86660000 来电都会到这里。这里的关键是顺序:把限时条件放在前面,兜底放在后面,FreeSWITCH 的匹配逻辑是"先命中先执行",一旦第一个命中并执行完,后面的 extension 不会再被检查。

参数说明:wday的取值范围是 1-7,对应周一至周日;hour使用 24 小时制,写法08:00-18:00表示包含两端。需要节假日另配时,可以用mday(月内日期)字段,再不行就拉 mod_distributor 做更细的外部日历判断,但绝大多数场景时间字段够用。注意:上面的第二个 extension 用play_and_get_digits做留言收集,参数里把vm_option设为 9 代表转语音信箱,但 FreeSWITCH 本身没有内置话务员语音信箱应用,这里只是按键收集后转分机,真正做语音留言需要再接 voicemail 应用。写这段想说明的是:时间路由的优先级顺序比你写的正则还重要,别把兜底 extension 放在第一个。

呼入路由里还有一类经常被忽略的需求:对指定主叫号码放行、对骚扰号码拦截。做法是把 caller_id_number 的匹配条件放在最前面,条件命中执行放行或挂断。由于 anti-action 是在条件失败时执行,你甚至可以写一条只匹配黑名单前缀的 extension,命中就挂断,未命中自然落到下一条 extension。注意 FreeSWITCH 对未在拨号计划中显式允许的呼叫,默认是拒绝的,所以黑名单拦截通常写成白名单模式更稳妥:先放行已知分机,再统一拒绝未知号码。

4. 呼出路由怎么配:网关、号码改写和多线路兜底

呼出路由的复杂度不在 dialplan 本身,而是网关、号码归一化和失败转移三件事。我把它拆成三步走。

4.1 先把 SIP 网关配好:gateway 命名与三个必调参数

呼出路由的第一步是有一个能用的外线网关。FreeSWITCH 的 SIP 网关定义在conf/sip_profiles/external/下的 XML 中,或者从conf/sofia.conf.xml里 include 网关文件进来。网关的概念可以这样理解:它描述了一个对端 SIP 服务器,以及 FreeSWITCH 以什么身份向它发起呼叫。

<include> <gateway name="gw-sip-trunk"> <param name="username" value="10086"/> <param name="password" value="ChangeMe"/> <param name="realm" value="sip.isp-example.com"/> <param name="proxy" value="sip.isp-example.com"/> <param name="register" value="true"/> </gateway> </include>

逻辑说明:gateway的name属性就是后面 dialplan 里使用的网关名,一经配置尽量别改,因为 dialplan 和状态查看命令都会引用它。username和password是向对端注册或鉴权用的账号;realm一般填对端 SIP 服务器的域名,proxy是实际把 INVITE 发往的地址。大部分中继业务里realm和proxy相同,但如果对端把注册域和呼叫域分开,两个值就不同了。

参数说明:register设为true时,FreeSWITCH 会向对端发 REGISTER,适合需要注册鉴权的中继;如果对端只收固定 IP 的呼叫、不许注册,就把register设为false,这时 username/password 仍要保留,用于 INVITE 的摘要鉴权。多数呼出不通的问题出在realm填错——很多人在realm里填成 IP 字符串,而对端要求填域名。配置好后,用fs_cli -x "sofia status gateway gw-sip-trunk"看注册状态,status 为 REGED 才说明网关侧就绪;status 不是 REGED 时先别碰 dialplan,因为大概率卡在账号密码或 realm 上。网关配置再配上一条路由转发规则,相当于把固定号码前缀转发到固定网关这件事声明清楚,也就是把"哪些号码走哪条外线"固定下来。

4.2 呼出选路核心:bridge 到 sofia/gateway 的写法

网关就绪后,呼出路由的核心就是一条 bridge 语句。分机拨 0 或拨 0 加号码的外呼,在 dialplan 里常见的路由是:

<extension name="outbound-call"> <condition field="destination_number" expression="^0(\d+)$"> <action application="set" data="outbound_number=${regex(${destination_number}|^0(\d+)$|$1)}"/> <action application="bridge" data="sofia/gateway/gw-sip-trunk/${outbound_number}"/> </condition> </extension>

逻辑说明:condition匹配的是用户拨出的号码,正则^0(\d+)$的意思是用户先拨 0,后面才是真实外线号码。命中后先把真实号码提取出来存进outbound_number,再通过sofia/gateway/gw-sip-trunk/这个目标语法发起呼叫。sofia/gateway/网关名/号码是 FreeSWITCH 呼出到网关的固定写法,网关名必须和 4.1 里gateway的 name 完全一致。

参数说明:${regex(...)}是 FreeSWITCH 内置字符串处理函数的调用方式,格式是源字符串|正则|替换表达式。上面用$1拿回第一个捕获组,也就是去掉前导 0 的真实号码。为什么不直接在 bridge 里写sofia/gateway/gw-sip-trunk/0${destination_number}?因为很多中继运营商要求来电是 E.164 格式(国家码开头),而分机用户习惯拨 0 开头,拆出来重组会更灵活。如果运营商要求加 0086 或 86 前缀,把 set 那行改成data="outbound_number=86${regex(...)}"即可。

主叫号码的改写也放在呼出路由里。很多中继会校验主叫号码格式,随便填会被拒。用下面两个变量在 bridge 前强制指定外显号码:

<action application="set" data="effective_caller_id_number=01012345678"/> <action application="set" data="caller_id_number=01012345678"/>

逻辑说明:effective_caller_id_number是 FreeSWITCH 最终对外发送的主叫号码,caller_id_number是通道里的原始主叫。有些中继只看前者,有些会两者都校验,建议两个一起写。如果外显号码是由运营商下发而不是自选的,就不要在 dialplan 里覆写,交给网关透传即可。

4.3 多网关轮询与失败转移:一条线路挂了,路由怎么换

生产中一条外线网关不够用是常态。FreeSWITCH 没有内置的多网关优先级自动选路模块,所以常见做法是利用 bridge 的失败顺序执行实现转移:第一个 bridge 失败后,会继续执行下一个 action。

<extension name="outbound-with-fallback"> <condition field="destination_number" expression="^0(\d+)$"> <action application="set" data="outbound_number=${regex(${destination_number}|^0(\d+)$|$1)}"/> <action application="bridge" data="sofia/gateway/gw-sip-trunk-a/${outbound_number}"/> <action application="bridge" data="sofia/gateway/gw-sip-trunk-b/${outbound_number}"/> <action application="bridge" data="sofia/gateway/gw-sip-trunk-c/${outbound_number}"/> <action application="play" data="/usr/local/freeswitch/sounds/all-lines-fail.wav"/> </condition> </extension>

逻辑说明:这段路由先尝试链路 A,bridge 返回失败(呼叫未建立、超时、被拒)后 FreeSWITCH 会自动执行下一个 action,也就是链路 B,再失败走 C,全部失败后播放提示音。注意这里实现的是"按顺序兜底",不是"负载均衡"。要做真正的轮流负载均衡,需要一个外层分发逻辑(比如 mod_distributor 或拨号计划前置脚本),我一般只在纯高可用场景用这里的顺序兜底,避免同一路由在不同链路上产生怪话务。

参数说明:bridge 的默认呼叫超时在网关没有注册成功时会很快失败,但在网关注册成功而对端不接时可能拖很久。可以在桥接前用变量控制超时,或在 bridge 目标前加{ignore_early_media=true}这类通道变量来避免被早期媒体卡住。更常见的做法是给每个网关单独设置call_timeout,再配合bridge的选项参数做精细控制。重点是:不要在 dialplan 里用continue="true"硬叠三个 bridge,那会绕晕呼叫详单,也会让后续计费逻辑难以为继。

5. 避坑:呼入呼出路由最常见的 5 个翻车点与排查

这一章聚焦实际配置过程中最容易浪费时间的几个坑,每一条都按"现象 → 原因 → 解决"来写。

5.1 分机号打了没反应,或进了别人的分机:condition 匹配顺序和正则错了

现象:拨 1000 没反应,或拨 1001 却被路由到了 1000。

原因:dialplan 里存在另一条更先命中的 extension,或者正则是^1000而不是^1000$,导致 1001、10001 都能命中 1000 规则;另外,同一个 context 里两条 extension 都匹配同一个号码时,先写在上面的优先。

解决:先看当前号码会命中哪条规则:

fs_cli -x "dialplan show 1000"

这个命令会输出 FreeSWITCH 针对号码 1000 解析出的可命中 extension 列表,按顺序从上到下就是实际执行顺序。把不该出现的规则删掉,或者给正则补上$。还有一种隐蔽情况:主叫呼入时进入了 public context,而你把规则写在 default context,导致呼叫根本不进这个 context。排查方法是看 SIP profile 与 context 的绑定关系,必要时用sofia status profile external确认外部呼叫落在哪个 context。

5.2 呼出号码少 0 或多国家码:号码归一化没做

现象:分机拨0 138 0000 0000,对方手机上显示13800000000,或反而显示013800000000,有的中继直接拒呼。

原因:运营商中继侧对号码格式有严格预期,有的要求不带 0、有的要求国家码开头,而拨号计划直接bridge了原始拨号串。

解决:统一在 bridge 前做一次号码加工:

<action application="set" data="outbound_number=${regex(${destination_number}|^0(86)?(\d+)$|$2)}"/>

逻辑说明:这个正则先吞掉用户拨号前导的 0,再吞掉可能的 86,把剩余号码提取为outbound_number。如果运营商要求带国家码,再在 bridge 目标里写86${outbound_number}。这里最需要固定的是"你的网关注册在哪个号码格式下",不要同一路由里一会儿传 0 开头一会儿不传,中继侧的号码格式是一份必须遵守的契约。我处理过的外呼故障,一半以上最终都指向号码格式和中继侧预期不一致。

5.3 呼出一直呼不通:先看网关注册状态,再动 dialplan

现象:路由写对了,分机拨号没报错,但听不到对端响应,或直接听到运营商提示无法接通。

原因:大概率是网关根本没有注册成功,dialplan 只是把呼叫发到了一个不存在的出口。

解决:用命令确认网关状态:

fs_cli -x "sofia status gateway gw-sip-trunk"

输出里看状态字段,重点关注 REGED(已注册)或错误码。如果是 401/407 反复出现,回查 username/password/realm;如果是 404,检查网关配置里的 domain 或拨号目标是否被对端承认;如果一直显示 UNREGED,先确认 FreeSWITCH 所在机器到对端 SIP 服务器的网络是否通,再确认 SIP 端口。记住,网关注册不成功时,改 dialplan 是无效的,因为请求根本出不了网关这道门。这条是我排障时最先检查的一步。

5.4 外呼后对方看到主叫号码不对:外显号码没设或设错

现象:呼出能通,但对方看到的不是公司总机号,而是一个随机的分机号或空号。

原因:dialplan 没设置effective_caller_id_number,或网关侧开启了主叫透传,把注册账号名透传过去了。

解决:在呼出路由的 bridge 前设置主叫变量(见 4.2 的 set 写法),并让中继侧确认外显号码在白名单内。如果主叫号码被运营商强制替换,那是中继策略问题,FreeSWITCH 侧改多少遍都不会生效。可以做一个简单的自测:用另一部手机打该中继的测试号码,看来电显示是否是预期号码,以此把问题边界切清楚。

5.5 改完 XML 路由不生效:没有 reloadxml,或文件编码有问题

现象:XML 文件改了,reloadxml也执行了,但拨号行为还是老的。

原因:可能没有执行 reloadxml(FreeSWITCH 不会自动监听 dialplan 文件变化),或语法错误导致整个 context 被拒绝加载,也可能文件被存成了带 BOM 的 UTF-8。

解决:执行 reload 并检查是否有语法错误:

fs_cli -x "reloadxml" fs_cli -x "dialplan show default"

如果dialplan show里看不到新加的 extension,说明文件在解析阶段就被拒了。去conf/dialplan/下找到对应 XML,用xmllint --noout检查,并确认编辑器保存为 UTF-8 无 BOM。这个坑在 freeswitch安装win 的场景里尤其突出:Windows 记事本另存为 UTF-8 时会塞 BOM 头,FreeSWITCH 解析 XML 会失败,肉眼却看不出区别。建议 Windows 下用 VSCode 或 Notepad++ 把编码切到 UTF-8(无 BOM)再保存。

6. 不占线路验证路由的三种命令与日常操作习惯

路由配完,验证是最容易被偷工减料的环节。生产环境里不可能每次改路由都真拨一遍电话占住线路。我常用的验证方式是 originate 命令:它可以在不占用分机的情况下,从 FreeSWITCH 内部发起一个呼叫,观察路由走向。

fs_cli -x "bgapi originate {origination_caller_id_number=01012345678}sofia/gateway/gw-sip-trunk/13800000000 &echo"

逻辑说明:originate的格式是通道地址 &应用,这里把呼叫发往网关gw-sip-trunk,号码 13800000000,呼叫建立后执行echo应用(回声测试)。这个方式可以完整走一遍呼出路由的 bridge 流程,又不会真的接通一个坐席。呼入侧的验证则可以用user来模拟:fs_cli -x "bgapi originate user/1000 &echo(PING)"能看到拨号计划是否能把呼叫定位到分机 1000。还有个更细的命令,fs_cli -x "dialplan route 86660000"可以直接展示号码在拨号计划里的完整命中路径,不用发起呼叫就能排查大半路由问题。

参数说明:bgapi表示后台异步执行,不会卡住 fs_cli;&echo后的(PING)是传给应用的参数,随便写一个字符串即可。验证期间,建议在另一个终端挂fs_cli -x "console loglevel debug"看业务日志,INFO 级别只能看到有没有 INVITE,看不到路由内部的判断分支。

我自己的操作习惯是:改路由前先跑一遍dialplan route记录基线,改完 reloadxml 再跑一遍对比;涉及网关变更时先看sofia status,再做一次 originate 闭环测试,最后才敢让业务真打。这套顺序帮我挡掉了好几次生产事故,也算是一点血泪经验换来的流程。路由配置这类东西没有太多玄学,剩下的无非是格式、顺序、变量名,以及把每一步验证动作做扎实。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询