项目背景
该项目涉及在设备端运行的 IoT 客户端,该客户端与服务器之间通过 WebSocket (WS) 保持实时连接,进行指令下发和响应。设备在开机时自动启动客户端,并连接至服务器,等待接收指令。以下是项目的具体行为流程:
- 设备开机
设备启动后,客户端程序自动启动,初始化 WebSocket 连接。 - 连接服务器
客户端通过 WebSocket 连接到服务器,建立稳定的通信通道。 - 等待指令下发
客户端保持连接状态,处于等待模式,等待从服务器接收到新的操作指令。 - 接收 OTA 升级指令
当服务器需要升级设备的软件或模块时,会通过 WebSocket 向客户端发送 OTA 升级指令。 - 执行 OTA 升级
客户端接收到 OTA 升级指令后,会使用pip
等工具下载新的软件包并安装。
概述
在设备执行 OTA 升级后,部分程序(如 Client 或新安装的模块)无法运行,经排查后确认问题与非正常关机导致的内存缓存丢失有关。该问题通过手动关机并使用 sync
命令成功避免,明确了缓存同步未完成时的关机操作可能会导致文件数据丢失,从而引发应用程序无法正常运行。
排错过程
1. 初步分析与假设
设备执行了由服务器发来的 OTA 升级指令,使用 pip
安装了新的版本包,并在安装完成后重启设备。重启后,发现 Client 或新安装的模块无法运行。通过查看 package 存放路径,发现安装的代码文件为空,文件大小为 0KB。起初怀疑可能是由于客户端权限问题导致的文件未能正确写入。
2. 权限排查
为了验证权限问题,进行了多次重试和检查。具体操作包括:
- 确认设备上安装的客户端程序的权限是否正确,特别是
pip
安装的新包。 - 比较其他正常运行的程序的权限设置,并确认与发生问题的程序权限一致。
- 检查
client
程序是否以 root 权限执行,排除了权限问题。
最终结果显示,权限设置没有问题,且 client
通过 rc.local
自启动,应该具备正常的 root 权限,因此可以排除权限问题。
3. 视频写入问题排查
在其他测试中,发现某些算法服务在运行时将视频文件写入磁盘,但文件大小为 0KB,表明文件写入操作未成功。由于其他算法服务在正常运行时都没有遇到过写入失败的情况,因此怀疑这个问题与代码文件为空的问题相关,初步认为可能是由文件系统或缓存的问题引起。
4. 系统关机流程分析
进一步分析设备的关机流程,该设备在断电关机时是通过长按按钮进行的,这种方式属于非正常关机。对于 Linux 系统而言,非正常关机会导致无法及时同步内存中的缓存数据至磁盘。当应用程序进行文件写入时,数据首先会被写入内存中的缓冲区,而非直接写入磁盘。内核使用页面缓存(Page Cache)机制来管理这些缓存,最终在一定时间内或通过 sync
命令手动触发时,才会将数据写入磁盘。
由于设备的非正常关机导致操作系统未能及时同步内存中的数据,缓冲区中的文件数据可能未能持久化到磁盘,造成文件丢失或为空的情况。因此,升级过程中可能的文件写入操作未被正确完成,导致新安装的模块代码文件大小为 0KB,从而导致程序无法运行。
5. 重现与确认
根据上述分析,进行了进一步的验证。操作流程如下:
- 手动安装软件包后立即进行断电关机,复现了文件为空的现象,验证了非正常关机与文件数据丢失之间的关系。
- 在安装软件包后,使用
sync
命令强制同步缓冲区的数据到磁盘后再关机,发现程序和新安装模块均能正常运行,文件没有丢失,问题得以解决。
结论与建议
通过本次排查,问题的根本原因已被确认:非正常关机导致内存缓存未及时同步到磁盘,进而导致安装的代码文件为空,导致应用程序无法正常运行。为避免类似问题再次发生,建议在后续工作中:
- 完善设备的关机流程,确保设备能够进行正常关机,以便系统能够正确同步内存缓存至磁盘。
- 在OTA升级等关键操作后,确保使用
sync
命令手动同步数据,避免数据丢失。 - 对于长期使用的设备,建议增加关机过程中的异常检测与日志记录,以便更快速地定位和解决此类问题。
后续改进
为避免断电引发的潜在问题,建议:
- 引入系统自动同步机制,在关键操作(如升级或写入数据后)后自动调用同步命令,减少人为疏漏。
- 设计合理的关机机制,确保所有数据被正确同步并写入磁盘,避免因突发电源问题导致数据丢失或程序异常。
通过以上措施,可以有效减少因硬件问题或操作失误带来的系统故障,提升系统的稳定性和可靠性。