工控设备4G流量管控与异常自愈:防跑流量、网络卡死复位方案

发布时间:2026/7/11 19:41:17
工控设备4G流量管控与异常自愈:防跑流量、网络卡死复位方案 工控设备4G流量管控与异常自愈防跑流量、网络卡死复位方案大家好我是黒漂技术佬。网络专题最后一篇咱们聊两个运维最头疼的问题流量跑飞了、网络卡死了。做无人设备的都懂4G流量费是持续成本。一台设备一个月跑几个G还好要是出bug跑几十上百G那账单能让老板跳起来。还有更头疼的——4G模块卡死了系统显示有网但啥都发不出去必须有人去现场重启设备。今天就给大家一套完整的流量管控异常自愈方案。一、为什么无人设备容易跑流量先分析一下流量都去哪了别光盯着APP发了多少数据很多流量是看不见的。流量消耗的几个来源来源说明可控性业务数据MQTT消息、心跳、状态上报、视频上传完全可控系统后台安卓系统自带的同步、检查更新、定位等部分可控其他APP工控机里预装的其他应用偷偷联网看ROM定制程度重连风暴网络不稳定时频繁重连、重试可控上一篇讲过异常bug死循环发请求、日志疯狂上传代码质量问题最可怕的是异常bug导致的流量暴增一天跑几十G都有可能。二、流量统计与监控要管控流量先得知道用了多少。获取4G流量使用量publicclassTrafficStatsManager{/** * 获取本次开机以来的移动数据流量 */publiclonggetMobileTrafficSinceBoot(){// Android自带的流量统计longrxTrafficStats.getMobileRxBytes();longtxTrafficStats.getMobileTxBytes();returnrxtx;}/** * 获取本APP的流量使用 */publiclonggetAppTraffic(intuid){longrxTrafficStats.getUidRxBytes(uid);longtxTrafficStats.getUidTxBytes(uid);returnrxtx;}}持久化流量统计TrafficStats重启就清零所以要自己存历史数据publicclassTrafficMonitor{privatestaticfinalStringKEY_LAST_BOOT_TRAFFIClast_boot_traffic;privatestaticfinalStringKEY_MONTH_TRAFFICmonth_traffic;privatestaticfinalStringKEY_STAT_MONTHstat_month;/** * 计算累计流量 */publiclonggetTotalMonthTraffic(){// 检查是不是新的月份StringcurrentMonthgetCurrentMonth();if(!currentMonth.equals(SpUtils.getString(KEY_STAT_MONTH,))){// 新月份清零SpUtils.putString(KEY_STAT_MONTH,currentMonth);SpUtils.putLong(KEY_MONTH_TRAFFIC,0);SpUtils.putLong(KEY_LAST_BOOT_TRAFFIC,0);return0;}// 本月历史累计 本次开机以来的增量longhistorySpUtils.getLong(KEY_MONTH_TRAFFIC,0);longcurrentBootTrafficStats.getMobileRxBytes()TrafficStats.getMobileTxBytes();longlastBootRecordSpUtils.getLong(KEY_LAST_BOOT_TRAFFIC,0);// 注意如果流量值变小了说明重启过用当前值作为增量longdeltacurrentBootlastBootRecord?(currentBoot-lastBootRecord):currentBoot;returnhistorydelta;}/** * 定期保存流量快照 */publicvoidsaveTrafficSnapshot(){longcurrentTrafficStats.getMobileRxBytes()TrafficStats.getMobileTxBytes();longmonthTotalgetTotalMonthTraffic();SpUtils.putLong(KEY_LAST_BOOT_TRAFFIC,current);SpUtils.putLong(KEY_MONTH_TRAFFIC,monthTotal);}}流量异常检测设置阈值超过了就告警publicclassTrafficAlarm{// 日流量阈值超过就告警比如100MBprivatestaticfinallongDAILY_THRESHOLD100*1024*1024;// 月流量阈值超过就限流比如2GBprivatestaticfinallongMONTHLY_THRESHOLD2L*1024*1024*1024;publicvoidcheckTrafficAlarm(){longdailygetDailyTraffic();longmonthlygetMonthlyTraffic();if(dailyDAILY_THRESHOLD){// 日流量超标告警reportAlarm(daily_traffic_exceed,daily);}if(monthlyMONTHLY_THRESHOLD){// 月流量超标进入限流模式enterTrafficSavingMode();reportAlarm(monthly_traffic_exceed,monthly);}}}三、流量管控策略1. 分级限流模式流量超了之后不是直接断网而是分级限制等级触发条件限制措施正常月流量 50% 阈值无限制正常运行预警月流量 50%~80%降低非关键数据上报频率减少心跳限流月流量 80%~100%停发低优先级消息视频上传暂停超量月流量 100%只保留核心业务开门、心跳其余全停publicclassTrafficSavingManager{publicvoidsetTrafficLevel(intlevel){switch(level){caseTRAFFIC_NORMAL:// 正常模式MqttManager.setHeartbeatInterval(60);// 60秒心跳VideoUploadManager.setEnabled(true);StatusReporter.setInterval(300);// 5分钟报一次状态break;caseTRAFFIC_WARNING:// 预警模式MqttManager.setHeartbeatInterval(120);// 2分钟心跳StatusReporter.setInterval(600);// 10分钟报一次break;caseTRAFFIC_LIMIT:// 限流模式MqttManager.setHeartbeatInterval(300);// 5分钟心跳VideoUploadManager.setEnabled(false);// 暂停视频上传StatusReporter.setInterval(1800);// 30分钟报一次break;caseTRAFFIC_BLOCK:// 超量模式只留最核心的MqttManager.setHeartbeatInterval(600);// 10分钟心跳VideoUploadManager.setEnabled(false);StatusReporter.setEnabled(false);// 停掉状态上报// 只保留开门指令通道break;}}}2. 视频上传流量管控视频是流量大户必须单独管只在闲时上传比如凌晨2点到6点流量便宜的时候传压缩再传降低分辨率、帧率、码率分片限速上传时限制速度别占满带宽影响业务WiFi优先有WiFi就用WiFi传没WiFi再考虑4G3. 防止后台偷跑流量工控机ROM一定要定制好关掉系统自动更新关掉应用商店自动更新关掉位置服务、同步服务不需要的APP直接删掉或者禁用网络权限经验一台干净的工控ROM待机一个月流量也就几十MB。四、4G模块卡死异常检测这是个老大难问题系统显示4G连着信号也有但就是发不出数据ping不通任何地址。卡死的几种表现网络接口显示已连接但所有请求超时信号强度正常但DNS解析全失败MQTT一直重连连不上探针全失败切换飞行模式也恢复不了卡死检测逻辑publicclassNetworkStuckDetector{privatestaticfinalintMAX_CONSECUTIVE_FAIL5;privateintconsecutiveFailCount0;/** * 每次探针失败调用一次 */publicvoidonProbeFailed(){consecutiveFailCount;if(consecutiveFailCountMAX_CONSECUTIVE_FAIL){// 连续失败多次可能是模块卡死了if(isModuleStuck()){onModuleStuckDetected();}}}/** * 探针成功了重置计数 */publicvoidonProbeSuccess(){consecutiveFailCount0;}/** * 判断是不是模块卡死 * 特征接口显示连接 信号正常 所有网络请求都失败 */privatebooleanisModuleStuck(){booleaninterfaceConnectedNetworkManager.isInterfaceConnected();booleansignalNormalSignalMonitor.getSignalLevel()1;booleanallProbeFailed!NetworkProbe.probeAll();returninterfaceConnectedsignalNormalallProbeFailed;}}五、4G模块异常自愈方案检测到卡死了怎么办有几招从轻到重。第一招数据连接开关软复位关掉再打开移动数据相当于让4G模块重新注册网络/** * 切换移动数据连接 * 需要系统权限 */publicvoidtoggleMobileData(){try{ConnectivityManagercm(ConnectivityManager)App.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);MethodsetMobileDataEnabledcm.getClass().getMethod(setMobileDataEnabled,boolean.class);// 先关setMobileDataEnabled.invoke(cm,false);// 等2秒Thread.sleep(2000);// 再开setMobileDataEnabled.invoke(cm,true);Log.i(Network,移动数据已重启);}catch(Exceptione){Log.e(Network,重启移动数据失败,e);}}第二招飞行模式切换比第一招狠一点整个基带重启/** * 切换飞行模式 * 需要系统权限 */publicvoidtoggleAirplaneMode(){try{Settings.Global.putInt(App.getContext().getContentResolver(),Settings.Global.AIRPLANE_MODE_ON,1);// 发广播通知系统IntentintentnewIntent(Intent.ACTION_AIRPLANE_MODE_CHANGED);intent.putExtra(state,true);App.getContext().sendBroadcast(intent);Thread.sleep(5000);// 等5秒// 关掉飞行模式Settings.Global.putInt(App.getContext().getContentResolver(),Settings.Global.AIRPLANE_MODE_ON,0);intent.putExtra(state,false);App.getContext().sendBroadcast(intent);}catch(Exceptione){Log.e(Network,切换飞行模式失败,e);}}第三招4G模块硬件复位最狠的一招直接给4G模块断电重启。需要硬件支持一般是通过GPIO控制/** * 4G模块硬件复位 * 需要厂商提供的接口 */publicvoidhardwareReset4GModule(){try{// 通过GPIO拉低模块电源GpioManager.setGpioValue(GPIO_4G_POWER,0);Thread.sleep(3000);// 断电3秒GpioManager.setGpioValue(GPIO_4G_POWER,1);// 重新上电// 等模块启动Thread.sleep(15000);Log.i(Network,4G模块硬件复位完成);}catch(Exceptione){Log.e(Network,4G模块硬件复位失败,e);}}自愈策略分级执行不要一上来就硬件复位从轻到重试检测到网络卡死 ↓ 第1次软复位开关数据连接 ↓ 等2分钟观察是否恢复 没恢复 → 第2次飞行模式切换 ↓ 等3分钟观察 没恢复 → 第3次硬件复位4G模块 ↓ 等5分钟观察 还没恢复 → 整机重启看门狗或者系统reboot ↓ 记录异常日志上报后台publicclassNetworkSelfHealing{privateinthealLevel0;publicvoidtryHeal(){healLevel;switch(healLevel){case1:toggleMobileData();scheduleCheck(120000);// 2分钟后检查break;case2:toggleAirplaneMode();scheduleCheck(180000);// 3分钟后检查break;case3:hardwareReset4GModule();scheduleCheck(300000);// 5分钟后检查break;case4:// 终极手段整机重启rebootDevice();break;}}publicvoidonHealSuccess(){healLevel0;// 恢复了重置等级}}六、长期在线稳定性保活心跳保活优化4G NAT网关有超时机制长时间没数据连接会被踢下线心跳间隔不要太长建议60~120秒心跳包尽量小减少流量弱网下适当延长心跳间隔减少失败率保持数据连接活跃有时候系统会把数据连接挂起定期发点小包保持活跃// 每5分钟发一次极小的网络请求保持连接活跃// 不要太频繁费流量publicvoidkeepConnectionAlive(){newThread(()-{try{// 发个DNS查询就行流量极小InetAddress.getByName(www.baidu.com);}catch(Exceptione){// 忽略}}).start();}七、踩坑经验坑1流量统计不准现象自己统计的流量和运营商账单对不上原因TrafficStats统计的是设备层的不包含底层协议开销而且重启会清零统计有误差解决以运营商数据为准自己的统计做相对参考就行设置阈值留余量坑2硬件复位把模块搞砖了现象频繁硬件复位4G模块偶尔会出现模块启动不起来原因断电时机不对模块正在写固件的时候断电就砖了解决不要频繁硬件复位至少间隔半小时以上尽量用软复位坑3飞行模式切不回来现象切了飞行模式之后4G再也搜不到网了原因部分ROM的bug飞行模式后基带没恢复解决加超时检测切飞行模式后5分钟还没网就硬件复位八、总结4G流量管控与异常自愈核心是提前防、出问题能自己修。流量管控方面先统计再管控分级限流重点管视频这种大户异常流量要告警防止bug跑飞流量ROM层面就要做干净减少后台偷跑异常自愈方面准确识别假死卡死状态从轻到重分级自愈软复位 → 飞行模式 → 硬件复位 → 整机重启自愈次数和频率要控制不能无限重试把这套做好设备在线率能提升一大截运维成本也能降下来。我是黒漂技术佬专注无人零售物联网实战。网络专题三篇到这里就结束了下一章进入MQTT通信专题聊聊物联网设备怎么跟云端稳定对话。有4G模块调不通的坑欢迎私信交流大家一起踩坑~