背景与痛点

许多网络运维人员都遇到过这样的场景:使用 RouterOS 管理多条 PPPoE 宽带线路(例如多条 ADSL、光纤宽带聚合),运营商每隔固定周期(常见为 48 小时、72 小时或 4 天)会强制断开 PPPoE 会话并触发重拨。当几十甚至上百条 PPPoE 连接同时被运营商踢下线时,所有线路会一起进入重拨流程,导致整个网络在接下来 1~2 分钟内完全瘫痪——业务中断、游戏掉线、视频卡顿,用户投诉不断。

更让人困惑的是:如果手动去重拨某一条线路(先禁用再启用),往往几秒钟就能重新获得 IP,几乎感觉不到断流。为什么运营商强制重拨就会导致长达 2 分钟的“集体罢工”?

原因很简单:运营商侧的重拨通常会伴随着后台认证服务器的瞬时压力、或客户端同时发起大量并发请求造成的拥塞。而手动单条重拨则避开了“洪水式”并发,认证速度快,断线时间极短。

解决思路

既然运营商定期踢线无法改变,我们可以主动抢占先机:在运营商强制重拨之前,我们自己逐个、有序地重拨每一条 PPPoE 连接。只要重拨间隔足够分散(例如每隔 30 秒重拨一条),每条线路只会有几秒钟的短暂中断,且不同线路的中断时间错开,整体网络几乎不受影响。

这就像火车站的检票口:如果几千人同时涌向一个入口,必然拥堵;如果安排多个入口并分批放行,队伍就顺畅得多。

下面给出的 RouterOS 脚本,可以自动检查所有 PPPoE 客户端的运行时长,一旦超过设定阈值(比如 4 天),就逐个执行“禁用→启用”重拨,每次重拨后等待 30 秒再操作下一条。

脚本详解

# =========================================================
# PPPoE 批量重拨脚本
# 功能:检查所有 PPPoE 连接,运行时间超过 4 天的自动重拨
# 重拨间隔:每个连接重拨后等待 30 秒
# =========================================================

:local maxDays 4
:local delaySeconds 30
:local logPrefix "【PPPoE批量重拨】"

:local thresholdSec ($maxDays * 86400)
:local renewedCount 0
:local totalChecked 0
:local ifaceList [/interface pppoe-client find]

:log info "$logPrefix 开始检查所有 PPPoE 连接(运行 > $maxDays 天则重拨)"

:foreach iface in=$ifaceList do={
    :local ifName [/interface pppoe-client get $iface name]
    :set totalChecked ($totalChecked + 1)

    :local uptimeStr ([/interface pppoe-client monitor $ifName once as-value]->"uptime")

    :if ([:len $uptimeStr] = 0) do={
        :log info "$logPrefix $ifName 当前未连接,跳过"
        continue
    }

    :local uptimeSec [:totime $uptimeStr]

    :if ($uptimeSec > $thresholdSec) do={
        :log info "$logPrefix $ifName 已运行 $uptimeStr(超过 $maxDays 天),正在重拨..."

        # 执行重拨
        /interface pppoe-client disable [find name=$ifName]
        /interface pppoe-client enable [find name=$ifName]

        :set renewedCount ($renewedCount + 1)

        :if ($renewedCount < [:len $ifaceList]) do={
            :delay $delaySeconds
        }
    } else={
        :log info "$logPrefix $ifName 已运行 $uptimeStr(未超过 $maxDays 天),无需重拨"
    }
}

:log info "$logPrefix 执行完成。共检查 $totalChecked 个连接,实际重拨 $renewedCount 个。"

关键参数说明

参数默认值含义
maxDays4连接运行超过此天数即触发重拨(建议小于运营商强制周期,比如运营商 5 天踢线就设为 4)
delaySeconds30每重拨完一条连接后等待的秒数,避免多条同时重拨

脚本工作流程

  1. 获取所有 PPPoE Client 接口列表。
  2. 遍历每个接口,读取其当前 uptime(在线时长)。
  3. 如果在线时长超过 maxDays(以秒计算),执行:

    • 记录日志
    • 禁用接口 → 启用接口(触发重拨)
    • 重拨计数 +1
    • 如果还有未处理的接口,等待 delaySeconds
  4. 如果在线时长未超阈值或连接已断开,则直接跳过。
  5. 最终输出总检查和实际重拨数量。

为什么这样能解决问题?

  • 主动预重拨:在运营商强踢之前(比如运营商周期是 5 天,我们在第 4 天做一次),主动刷新会话。此时运营商侧不会同时踢掉所有线路,重拨过程与手动重拨一样平滑。
  • 串行处理 + 间隔:避免大量连接在同一秒发起认证请求,极大降低 PPPoE 认证服务器的瞬时压力,也避免了 RouterOS 自身并发连接过多可能导致的资源问题。
  • 精准判断:只处理运行时间超阈值的连接,已重拨过的连接 uptime 会重置,下次检查时不会重复操作。

部署步骤

1. 添加脚本到 RouterOS

通过 WinBox 或 SSH 进入 RouterOS:

/system script add name="pppoe-auto-renew" source="上述脚本内容"

2. 设置定时任务

为了让脚本每天自动运行一次(例如凌晨低峰期),添加 scheduler:

/system scheduler add name="daily-pppoe-renew" on-event="/system script run pppoe-auto-renew" start-time=03:00:00 interval=1d
建议将执行时间设在业务低峰期,比如凌晨 2:00~5:00。如果某条线路刚好在白天业务高峰时达到了阈值,也不必担心——单条线路重拨只中断几秒钟,用户基本无感。

3. 手动测试

首次运行前可以先测试:

/system script run pppoe-auto-renew

通过日志(/log print)观察执行结果。

效果对比

场景中断时长影响范围
运营商集体强制重拨约 1~2 分钟所有线路同时断,全网瘫痪
脚本主动预重拨每条线路 < 10 秒同一时间只有一条线路中断,其他线路正常

对于链路聚合、PCC 负载均衡、多线备援等场景,单条线路短暂中断不会导致整体断网,业务几乎无感知。

注意事项

  1. 运营商周期摸底:建议先观察日志,确定运营商强制重拨的间隔(通常为 2~5 天),将 maxDays 设置为比该间隔小半天或一天。例如运营商 72 小时(3 天)踢线,则设 maxDays 为 2。
  2. 间隔时间调整delaySeconds 可根据线路数量调整。如果只有几条线路,可设为 10~20 秒;如果有上百条,建议 30~60 秒,避免瞬间发起过多认证请求。
  3. 日志监控:通过 /log find where topics~"pppoe" 观察重拨是否成功,确认每次重拨后 uptime 被重置。
  4. 拨号依赖:如果 PPPoE 接口绑定了特定网口或 vlan,确保禁用/启用操作不会影响底层接口。

进阶优化

  • 动态延迟:可以根据当前在线连接数计算延迟,例如 :delay (3600 / $totalLines),让重拨均匀分布在一小时内。
  • 失败重试:重拨后检查接口是否成功获取 IP,若失败则再次重试并延长等待时间。
  • 通知推送:结合 Telegram 或 E-mail 脚本,将重拨结果发送给管理员。
最后修改:2026 年 06 月 16 日
如果觉得我的文章对你有用,请随意赞赏