OpenWrt无网络连接时重启系统

通过OpenWrt与光猫单线利用,并通过UDPxy组播转单播,实现了在局域网内任意设备观看IPTV,但是在使用一段时间后网络会断网,但IPTV却可以正常观看,也看不出是哪出了问题,感觉是网络“串了”,看不懂日志也解决不了,但是重启OpenWrt才能恢复网络连接,而且这样的情况会经常有,有时几天有时十几、二十几天,我在家还好,网络不行了就重启一下系统。如果我不在家,家里人就得拔电重插,这样达到重启OpenWrt系统的目的。两种方法都得手动重启,很麻烦。

定时重启

后来就想到使用OpenWrt自带的定时重启。设定为每天重启一次,这样最大化的减少间隔。但感觉这有点“浪费”,并不是对症的靶向治疗。而且这个不能保证百分百有效,因为网络无法连接是不定时的出现情况,前面也说了有时几天有时十几、二十几天,但不能保证以后就是这种规律,但是不排除这种情况:系统刚重启完网络可能就不能用了, 只能在发现后手动再次重启。治标不治本。

系统启动

后来就想到在检测到网络无法连接时自动重启OpenWrt不就解决了吗?

使用开机启动的方法将重启脚本设置成开机启动,但是这只能保证脚本开机自启动成功,不能保证持续运行,万一脚本意外中断就无法检测网络。遂放弃此方法。

系统服务

要找到一个自动启动而且要守护运行的方法,那就只有一个办法了那就是系统服务的方法了。

系统服务最重要的就是能守护进程,就像WindOpenWrtws系统的服务一样可以设置重启策略,这样一来,即便脚本意外退出,系统服务也会将它重启保持持续运行。

				
					#!/bin/sh /etc/rc.common
START=99
USE_PROCD=1
PROG=/root/check-network


start_service() {
        cat >$PROG <<EOF
#!/bin/sh

# 日志文件路径,建议绝对路径
LOGFILE="/root/check-network.log"

# 记录重启时间文件
REBOOT_LOG="/root/check-network-reboot.log"
# 文件初始化
cat /dev/null > \$REBOOT_LOG


# 尝试访问的URL
CHECK_URL="https://www.baidu.com"
# 连续失败次数
FAILURE_COUNT=0

# 高级配置:5分钟之内达到重启次数2次,往后不会再重启
# 逻辑:
# 1.每次执行重启前记录当前时间
# 2.每次需要重启前先判断最近2次的重启间隔是否大于5分钟,大于5分钟则重启,小于等于5分钟则不重启
TIME_INTERVAL=\$((5 * 60))
REBOOT_TIME=2

while true; do
    # 使用curl尝试访问外部网站,并获取HTTP状态码,超时时间5秒
    STATUS_CODE=\$(curl -m 5 -o /dev/null --silent --head --write-out '%{http_code}\n' "\$CHECK_URL")

    # 检查状态码是否为200
    if [ "\$STATUS_CODE" != "200" ]; then
        # 如果不是200,则增加失败次数
        FAILURE_COUNT=\$((FAILURE_COUNT + 1))
        # 记录到日志文件
        echo "\$(date): Failed to connect (\$STATUS_CODE). Count: \$FAILURE_COUNT" >> "\$LOGFILE"

        # 如果连续失败两次,则进入重启判断环节
        if [ "\$FAILURE_COUNT" -eq 2 ]; then
            # 重置失败次数
            FAILURE_COUNT=0
            # 判断是否需要重启
            if [ "\$(wc -l < \$REBOOT_LOG)" -ge \$REBOOT_TIME ];then
                if [ "\$(tail -n \$REBOOT_TIME \$REBOOT_LOG | sed 's/\n/ /g' | awk -v k=\$REBOOT_TIME '{print \$k - \$1}')" -ge \$TIME_INTERVAL ];then
                    echo "\$(date): Restarting system due to continuous network failures." >> "\$LOGFILE"
                    echo "\$(date +%s)" >> \$REBOOT_LOG
                    reboot
                    
                fi
            else
                echo "\$(date): Restarting system due to continuous network failures." >> "\$LOGFILE"
                echo "\$(date +%s)" >> \$REBOOT_LOG
                reboot
            fi
        fi
    else
        # 如果连接成功,则重置失败次数
        FAILURE_COUNT=0
        # 连接成功不输出日志
        # echo "\$(date): Network connection is good (\$STATUS_CODE)." >> "\$LOGFILE"
    fi

    # 等待10秒再次检查
    sleep 10
done
EOF
        chmod +x $PROG
        procd_open_instance
        procd_set_param command $PROG
        procd_set_param respawn
        procd_close_instance
}
				
			

这个脚本的作用是:每10秒检测一次网络连接,如果连续两次检测到无法连接网络则会重启,而且限制在五分钟内只能重启两次。这就避免了非路由器故障而导致的无网络连接的循环重启。

为什么使用curl的方法而不是ping呢?因为我在路由器上安装着小猫咪,使用小猫咪的话,ping的都是小猫咪,也就无法检测网络连接状态了。

将以上内容上传到OpenWrt的/etc/init.d目录下,名称随意,并赋予读取、执行权限。

注意:前要将以上内容转换成Linux格式的换行符Unix(LF)格式再上传到OpenWrt上。我这是使用的Notepad++,其它自行解决。

然后在OpenWrt里找到系统-启动项,找到添加的服务,并启用该服务。这里提一下,显示启用时为已开启开机自启动。这样就可以在系统启动时启动该服务。点击启动则立即开始运行,即在当前状态下开始运行。

或者使用以下命令控制该服务:

启用开机启动

				
					/etc/init.d/netwok-test enable
				
			

禁用开机启动

				
					/etc/init.d/netwok-test disable
				
			

手动启动

				
					/etc/init.d/netwok-test start
				
			

手动停止

				
					/etc/init.d/netwok-test stop
				
			

查看状态

				
					/etc/init.d/netwok-test status
				
			
0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论!x