×

飞牛影视重复媒体与启动失败排查:一条 .curlrc 代理配置引发的连锁故障

Falcon 2026-08-29 views:
自动摘要

正在生成中……

问题背景

飞牛影视的媒体库突然出现大量重复项目:同一个视频文件在界面中显示两到三次,但文件管理器里实际上只有一个源文件。

飞牛影视媒体库中同一个视频被重复收录

随后,应用中心也开始出现异常:影视应用无法正常启用,点击“启用”后长期停留在“启动中”,最终提示本地应用启动失败。

飞牛影视提示本地应用启动失败

  • 影视应用显示“未启用”;
  • 点击“启用”后一直停留在“启动中”;
  • 最终提示“本地应用启动失败”;
  • 后台出现多个 trim-media 进程;
  • 强制终止后,进程有时又会被重新拉起。

最初看起来像是媒体数据库损坏,甚至一度考虑卸载重装。但深入排查后发现,根因并不在影视应用本身,而是一条全局 curl 代理配置。

一、确认重复的是索引,而不是文件

首先检查媒体源目录,确认同名视频在文件系统中只有一个实体,并不存在重复文件或硬链接。

进一步检查影视数据库后发现:

  • 相同文件路径对应多个不同的媒体 GUID;
  • CleanVideos 中有 19 个文件路径发生重复;
  • 共存在 38 条多余数据库记录;
  • 部分文件在界面中正好显示三次。

因此可以确定:

重复媒体来自影视数据库索引,而不是磁盘上的源文件。

这也意味着,直接删除源视频不仅不能解决问题,反而可能造成数据损失。

二、发现多个 trim-media 进程

检查影视进程和 8005 端口:

pgrep -a -x trim-media
ss -ltnp 'sport = :8005'

结果显示,系统中同时存在多个 trim-media 进程,但只有第一个进程成功监听 8005。

影视日志中则出现了明确的端口冲突:

listen tcp :8005: bind: address already in use
listen udp 0.0.0.0:7359: bind: address already in use

问题在于,后续进程虽然无法绑定端口,却没有立即退出,仍然可能继续运行文件监听、扫描和数据库任务。

于是形成了这样的结果:

多个 trim-media 实例
→ 同时扫描同一个媒体目录
→ 分别向数据库写入媒体记录
→ 同一路径生成多个 GUID
→ 媒体库出现重复项目

三、是谁在重复启动 trim-media

通过进程父子关系,找到了完整启动链:

systemd
└─ /usr/trim/bin/trim_app_center
   └─ /var/apps/trim.media/cmd/main start
      └─ trim-media

真正发起启动的是飞牛应用中心服务:

trim_app_center.service

影视并没有单独的 systemd 服务,而是由应用中心调用应用自带的控制脚本启动。

影视控制脚本位于:

/var/apps/trim.media/cmd/main
/var/apps/trim.media/cmd/common

其中,脚本通过下面的请求判断影视是否启动成功:

curl -s --max-time 3 localhost:8005/v/api/v1/sys/pid

正常情况下,该接口应该返回当前 trim-media 的 PID。

但实际现象是:

  • 影视已经成功监听 8005;
  • PID 接口检查却一直失败;
  • 控制脚本不断记录 trim.media is not running
  • 应用中心因此长期停留在“启动中”;
  • 自动重试或再次点击“启用”时,又会启动新的实例。

更麻烦的是,启动脚本没有单实例锁,状态检查也没有核对 PID 文件或现有进程。因此只要 PID 接口检查失败,每次启动任务都可能创建一个新的 trim-media

四、PID 接口真的坏了吗

一开始很自然地怀疑:

localhost:8005/v/api/v1/sys/pid

这个接口可能发生了兼容性问题。

但使用详细模式测试后发现,curl 并没有直接访问本机 8005,而是连接到了 Mihomo 的 SOCKS5 代理:

Trying <MIHOMO_IP>:7890...
SOCKS5 connect to localhost:8005

继续检查 root 用户的配置:

nl -ba /root/.curlrc

发现其中配置了全局代理:

-x socks5h://<MIHOMO_IP>:7890

这就是整个问题的关键。

为什么 socks5h 会影响 localhost

socks5h 中的 h 表示由代理端解析目标主机名。

因此,当系统执行:

curl localhost:8005

请求流程实际上变成了:

飞牛主机
→ Mihomo SOCKS5 代理
→ 代理端解析 localhost
→ localhost 指向代理所在环境,而不是飞牛主机

影视的 8005 端口明明监听在飞牛主机上,但请求却被送到了代理端的 localhost,当然无法获得 PID。

应用中心运行在 root 身份下,因此它调用的 curl 会自动读取:

/root/.curlrc

这也解释了为什么手动访问影视正常,而应用中心始终判断启动失败。

五、最终解决方法

最终同时采用了两层修复。

1. 为本机地址设置代理例外

/root/.curlrc 中加入:

--noproxy localhost,127.0.0.1,::1

完整配置可写成:

--connect-timeout 10
--noproxy localhost,127.0.0.1,::1
-x socks5h://<MIHOMO_IP>:7890

这样:

  • 外部网络请求仍然经过 Mihomo;
  • localhost127.0.0.1::1 始终直接连接本机;
  • 其他依赖 curl 的本地系统服务也不会被错误送入代理。

2. 让影视控制脚本忽略 .curlrc

影视控制脚本中有两处 PID 请求,分别用于状态检查和停止服务。

将原命令:

RESPONSE=$(curl -s --max-time 3 $URL)

改为:

RESPONSE=$(curl -q -s --max-time 3 "$URL")

这里的 -q 必须放在第一个参数位置,其作用是禁止 curl 加载默认配置文件。

两处都需要修改:

/var/apps/trim.media/cmd/common

对应功能分别是:

  • daemon_status:判断服务是否已经启动;
  • stop_daemon:停止服务前获取 PID。

--noproxy 解决系统范围的本机直连问题,curl -q 则为影视启动脚本增加一层独立保护。

需要注意:影视应用升级后,官方安装包可能覆盖控制脚本,因此 .curlrc 中的 noproxy 规则才是更加持久的基础修复。

六、修复后的验证

修改完成后,分别测试普通 curl 和忽略配置文件的 curl

curl -sv --max-time 3 \
  localhost:8005/v/api/v1/sys/pid

curl -q -sv --max-time 3 \
  localhost:8005/v/api/v1/sys/pid

两次请求均直接连接:

127.0.0.1:8005

接口返回:

HTTP/1.1 200 OK

并正确输出当前 PID。

最后检查应用状态:

pgrep -a -x trim-media
ss -ltnp 'sport = :8005'
appcenter-cli status trim.media

验证结果:

  • 只有一个 trim-media 进程;
  • 8005 只有一个监听者;
  • 应用中心状态为 running
  • 飞牛影视可以正常打开;
  • 不需要卸载重装。

七、排查过程中得到的经验

不要看到重复媒体就直接删除文件

应先判断重复发生在文件系统还是媒体数据库。相同路径对应多个数据库记录,通常意味着扫描器或多个服务实例重复写入。

UI 状态不等于实际状态

应用中心显示“启动中”时,服务可能已经启动。应同时检查:

pgrep
ss
日志

不要连续点击“启用”

如果第一次启动已经创建了后台进程,但健康检查失败,重复点击可能继续创建新实例。

谨慎使用 root 用户的全局代理配置

/root/.curlrc 不只影响手动执行的命令,也可能影响所有以 root 身份调用 curl 的系统服务和应用脚本。

全局配置代理时,至少应排除:

localhost,127.0.0.1,::1

本地健康检查应避免继承用户配置

系统服务中的本地健康检查,更稳妥的写法是:

curl -q -s --max-time 3 \
  http://127.0.0.1:8005/v/api/v1/sys/pid

更完善的启动脚本还应加入:

  • PID 文件核验;
  • 进程唯一性检查;
  • flock 单实例锁;
  • 端口占用检查;
  • 启动失败后终止残留进程。

总结

这次故障表面上表现为三个独立问题:

  • 飞牛影视媒体库重复;
  • 应用中心一直停留在“启动中”;
  • 后台存在多个 trim-media 进程。

实际上,它们来自同一条故障链:

/root/.curlrc 强制 localhost 走 socks5h
→ PID 健康检查访问了错误的 localhost
→ 应用中心误判影视没有启动
→ 重复拉起 trim-media
→ 多个实例同时扫描和写数据库
→ 媒体库产生重复记录

最终通过为本机地址设置 noproxy,并让影视控制脚本使用 curl -q,恢复了正确的状态检测和单实例运行。问题解决后,影视可以正常启动,无需重新安装。

本文收录于