☰
👁️ 预览
取消
💾 保存
C
Claude
▾
C
Claude
claude@note.center
🔔
消息通知
🔄
账号切换
⚙️
设置
🚪
退出登录
Markdown
富文本
# 视频服务运维故障排查 · 完整知识体系 > 学习日期:2026-07-02 > 涵盖11个常见故障场景,从概念到命令,从排查思路到解决方案 --- ## 一、基础知识 ### FFprobe 速查 FFprobe 是 FFmpeg 全家桶中的视频文件"体检仪"。 | 命令 | 作用 | |------|------| | `ffprobe -v error file.mp4` | 静默检查文件是否损坏(无输出=正常) | | `ffprobe -v error -show_entries stream=codec_name,width,height file.mp4` | 查看视频编码、分辨率 | | `ffprobe -v error -show_entries stream=codec_type,codec_name,width,height -of json file.mp4` | JSON格式输出(最常用) | | `ffprobe -v error -show_entries stream=index,codec_type,duration -of json file.mp4` | 对比音视频时长 | JSON输出示例: ```json { "streams": [ {"codec_type": "video", "codec_name": "h264", "width": 1920, "height": 1080}, {"codec_type": "audio", "codec_name": "aac"} ] } ``` | 字段 | 含义 | |------|------| | codec_type | "video"=视频流, "audio"=音频流 | | codec_name | h264 / hevc / vp9 等编码格式 | | width / height | 视频分辨率 | ### 转码概念 转码 = 把用户上传的原始视频转换成服务器统一标准格式的过程。 ``` 用户上传(千奇百怪) 转码后(统一标准) MOV / H.265 / 4K ——→ MP4 / H.264 / 1080p + 720p 版本 + 480p 版本 + 封面图 ``` 为什么要转码: - 格式统一:不同浏览器/设备支持不同的格式 - 兼容性:H.264 是所有浏览器都支持的编码 - 多码率:根据用户网速自动切换清晰度 - 封面图:从视频中抽取首帧生成 ### 转码排查三件套 ```bash # ① 文件大小——是不是0KB? ls -lh uploads/video.mov # ② ffprobe检查 ffprobe -v error uploads/video.mov # ③ 看真实文件类型(不看后缀) file uploads/video.mov ``` --- ## 二、播放质量类 ### 场景①:视频黑屏/加载不出来 **工单特征:** 一个视频黑屏,其他视频正常,文件存在。 **排查流程:** ``` 用户反馈视频无法播放 │ ├─ 其他视频也异常? → 全局问题(服务/CDN) │ └─ 只有这个视频? → 聚焦文件本身 │ ├─ ffprobe 检查视频流 │ ├── 无视频流(只有音频)→ 转码失败/上传了错误文件 │ ├── 编码浏览器不支持(HEVC/H.265)→ 转码兼容格式 H.264 │ ├── 文件损坏 → 重新上传转码 │ └── 视频正常 → 查播放器/协议/CDN │ └─ file 命令确认真实文件类型 ``` **常见编解码兼容性:** | 编码 | 浏览器兼容性 | |------|------------| | H.264 (AVC) | 所有浏览器 ✅ | | H.265 (HEVC) | Safari ✅, Chrome/Edge ⚠️ 部分支持 | | VP9 | Chrome/Firefox/Edge ✅, Safari ❌ | ### 场景②:播放卡顿、频繁缓冲 **工单特征:** 晚8~10点卡顿,白天正常。 **核心判断:** 高峰期带宽瓶颈。 **排查流程:** ``` 高峰期卡顿 │ ├─ 查带宽监控(云监控 / iftop / sar -n DEV 1 3) │ ├── 带宽没打满 → 查 CPU/IO/连接数 │ └── 带宽打满 ✓ → 带宽瓶颈 │ │ │ ├─ 没接 CDN → 建议上 CDN │ │ │ └─ 有 CDN → 查 CDN 命中率(curl -I 看 X-Cache 头) │ │ │ ├─ HIT 高 → 正常流量暴涨 │ │ │ └─ 大量 MISS → 排查四个方向: │ ① TTL 太短 → 加长(视频推荐 7~30 天) │ ② cache_key 参数不同 → 忽略 URL 参数 │ ③ 没做预热 → 上线前预热 │ ④ 大文件分片回源 → 改用 HLS 切片 ``` **紧急止血:** ```nginx # Nginx 限速限连接 limit_rate 1M; limit_conn addr 1; # CDN 带宽封顶(云厂商控制台) ``` **视频资源合理 TTL:** - 视频文件 (.mp4/.ts) → 7~30 天 - 封面图/缩略图 → 3~7 天 - 字幕文件 (.vtt) → 1~7 天 - HLS m3u8 索引文件 → 2~5 秒(直播场景特殊) ### 场景③:音画不同步 **工单特征:** 画面和声音对不上,且越往后延迟越严重。 **根因:** 转码时帧率参数错误(如源文件 24fps 被设成 30fps),导致时间戳逐帧偏移累加。 **排查方法:** ```bash ffprobe -v error -show_entries stream=index,codec_type,duration -of json video.mp4 # 对比视频流和音频流的总时长是否一致 # 如果视频 5400s,音频 5398.5s # → 视频比音频长 1.5s,到结尾时音画差 1.5 秒 ``` **修复:** ```bash ffmpeg -i input.mp4 -c:v libx264 -r 24 -c:a copy output.mp4 # 锁定正确帧率重新编码视频流,音频流直接复制 ``` --- ## 三、缓存与 CDN 类 ### CDN 三兄弟(核心概念) | 操作 | 做什么 | 场景 | |:----:|--------|------| | 🔄 刷新 (Purge) | 删除 CDN 缓存,下次请求回源拉新 | 内容更新了(紧急修复) | | 🔥 预热 (Preload) | 主动把资源推到 CDN 节点 | 新内容上线前(提前缓存) | | 🚫 封禁 (Block) | 禁止 URL 通过 CDN 访问 | 资源下架/违规内容 | ### CDN MISS 四个排查方向 1. **TTL 太短**:缓存时间短导致频繁回源 2. **cache_key 参数问题**:URL 带随机参数(如 ?t=timestamp)导致每次都是 MISS 3. **没做预热**:新资源上线没提前推到 CDN 节点 4. **大文件分片回源**:超大文件无法完整缓存,Range 请求穿透 ### 场景④:缓存未更新 **工单特征:** 后台改了封面图/标题,用户看到还是旧的。 **排查流程:** ``` "封面图还是旧的" │ ├─ 无痕窗口 / Ctrl+F5 强制刷新 │ └── 能解决 → 浏览器缓存 ✅ │ ├─ curl -I 看 X-Cache │ └── HIT → CDN 缓存了旧的 │ └── curl 直达源站(绕 CDN) │ ├── 源站已更新 → CDN 需要刷新 │ └── 源站未更新 → 找后端 │ └─ 解决方案对比: ├── 改名重新上传(最彻底,需改前端代码) ├── CDN 控制台刷新(紧急修复,即时生效) └── 等 TTL 过期(不推荐) ``` ### 场景⑤:CDN 预热/刷新策略 **周更剧集运维节奏参考:** - 周三:转码完成,上传到源站 - 周四 14:00:预热到 CDN 节点(留6小时同步) - 周四 20:00:用户直接 HIT ✅ - 随时:如果运营要求替换内容 → 刷新对应 URL 旧视频一般保留,不封禁(用户可能需要回看往期内容)。 ### 场景⑥:突发带宽飙升 **工单特征:** 带宽从 100Mbps 几分钟飙到近 1Gbps。 **核心原则:先保护,再排查。** 犹豫的每一秒都在烧钱(云厂商按 GB 计费)。 **紧急保护:** - CDN 控制台设带宽封顶阈值 - Nginx 限速/限连接 **排查方法:** ```bash # 按流量大小排序,看什么 URL 消耗带宽最多 #head -1 /var/log/nginx/access.log awk '{print $7, $10}' /var/log/nginx/access.log | \ awk '{sum[$1]+=$2} END {for(u in sum) printf "%.2f MB %s\n", sum[u]/1024/1024, u}' | \ sort -rn | head -10 #{print $7, $10} 从原始日志里挑出"URL路径"和"字节数"两列;{sum[$1]+=$2} 针对这两列,按URL分组累加字节数 ``` **三看判断法:** 1. 流量集中在 1~2 个 URL → 视频突然火了(正常) 2. 流量分散在大量 URL → 爬虫/CC 攻击 3. 请求集中在非视频路径(如 /api/)→ 异常攻击 **扩容不是第一选择,先排查优化方向。** ### 场景⑦:热点视频导致源站压力大 **工单特征:** CDN 命中率高、带宽正常,但源站 CPU/连接数爆了。 **关键发现:** 动态 API 不能被 CDN 缓存。 ```bash # 按请求次数统计(不是按流量) awk '{print $7}' /var/log/nginx/access.log | \ sort | uniq -c | sort -rn | head -10 ``` **动态接口能否缓存?** - 所有人返回的数据一样 → ✅ 能加 Redis / Nginx 缓存 - 每人每次返回不同(如播放 token)→ ❌ 不能缓存,改用限流/扩容 ```python # Redis 缓存示例(伪代码) def get_video_info(video_id): cache_key = f"video:info:{video_id}" data = redis.get(cache_key) if data: return data # 直接返回,不查数据库 data = db.query("SELECT * FROM videos WHERE id=?", video_id) redis.setex(cache_key, 300, data) # 缓存5分钟 return data ``` --- ## 四、上传与处理类 ### 场景⑧:上传失败/超时 **工单特征:** 2GB 大文件上传到 80% 失败,小文件正常。 **三层超时排查:** ``` 用户浏览器 → Nginx → 应用服务器 (Flask/Gunicorn) 默认 60s proxy_read_timeout 60s Gunicorn timeout 30s ``` ```nginx # Nginx 上传配置 client_max_body_size 5G; # 文件大小上限 proxy_read_timeout 600s; # 读超时 proxy_send_timeout 600s; # 写超时 proxy_request_buffering off; # 关缓冲(大文件) ``` ** HTTP 错误码速查:** - 413 Request Entity Too Large → client_max_body_size 太小 - 504 Gateway Timeout → proxy_read_timeout 超时 - 502 Bad Gateway → 应用进程挂了 **最佳实践:** 分片上传 + 断点续传,而不是单纯调超时。 ### 场景⑨:转码失败 **工单特征:** 用户上传 MOV 视频,转码状态:失败。报错 `Invalid data found when processing input`。 **报错含义:** FFmpeg 读不懂这个文件。 **常见原因:** - 文件损坏(上传中断,只传了一半) - 格式伪装(文件名是 .mp4,实际是 HTML 或其他) - 空文件(0KB) - 加密 / DRM 保护 - 编码器不支持(罕见冷门格式) **排查:** ```bash # ① 文件大小 ls -lh uploads/video.mov # ② ffprobe 检查 ffprobe -v error uploads/video.mov # ③ 看真实文件类型 file uploads/video.mov # 正常输出:ISO Media, Apple QuickTime movie # 异常输出:HTML document, UTF-8 Unicode text(实际上是网页) ``` --- ## 五、平台兼容类 ### 场景⑩:部分用户能看,部分不能 **工单特征:** 北京/上海正常,广东/四川看不了。文件、转码、CDN 配置都正常。 **根因:** 特定地区 CDN 节点故障 / 跨运营商 / DNS 解析错误。 **排查方法:** ```bash # 伪造来源 IP,模拟不同地区用户 curl -H "X-Forwarded-For: 广东IP地址" -I https://cdn.example.com/video.mp4 # X-Forwarded-For 是 HTTP 头,用来标识原始请求 IP # CDN 会根据这个头判断用户来源,分配对应区域的节点 # -I 只返回响应头,不下载正文 # 补充排查 ping cdn.example.com # 看 DNS 解析是否正确 traceroute cdn.example.com # 看网络路径 ``` **可能原因与解决:** - CDN 节点宕机 → 联系 CDN 厂商 - 跨运营商(电信/联通/移动)→ 上全网 CDN 或 BGP - DNS 解析到错误 IP → 检查 DNS 配置,等 TTL 刷新 ### 场景⑪:某些浏览器/设备播放异常 **工单特征:** Chrome 黑屏但有声音,Safari 正常。 **根因:** 视频编码不被 Chrome 支持(如 H.265)。 **各浏览器编码支持:** | 浏览器 | H.264 | H.265 | VP9 | |:------:|:-----:|:-----:|:---:| | Chrome | ✅ | ⚠️ 部分 | ✅ | | Safari | ✅ | ✅ | ❌ | | Firefox | ✅ | ⚠️ 部分 | ✅ | | Edge | ✅ | ⚠️ 部分 | ✅ | **解决方案:** 转码一份 H.264 版本作为兼容格式。 --- ## 六、常用排查命令汇总 ### 文件检查 ```bash ffprobe -v error -show_entries stream=codec_name,width,height -of json video.mp4 file video.mp4 ls -lh video.mp4 ``` ### CDN 检查 ```bash curl -I https://cdn.example.com/video.mp4 # 看 X-Cache 状态 curl -H "X-Forwarded-For: 地区IP" -I URL # 模拟地区请求 ``` ### 服务器负载 ```bash top # CPU iftop -i eth0 # 实时带宽 sar -n DEV 1 3 # 网卡流量统计 ``` ### 日志分析 ```bash # 按请求次数排序 awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -10 # 按流量大小排序(字节转 MB) awk '{print $7, $10}' access.log | \ awk '{sum[$1]+=$2} END {for(u in sum) printf "%.2f MB %s\n", sum[u]/1024/1024, u}' | \ sort -rn | head -10 ``` ### 转码 ```bash ffmpeg -i input.mov -c:v libx264 -c:a aac output.mp4 ``` --- ## 七、核心排查思维 1. **先保护,再排查** — 突发状况(带宽飙高)先止血,再慢慢找原因 2. **先优化,再扩容** — 扩容是最后手段,不是第一选择 3. **先局部,再全局** — 一个文件有问题?先看文件本身,别先怀疑整个服务 4. **变更前先沟通确认** — 改参数前问清楚影不影响其他业务,跟相关方确认 --- ## 八、涉及的核心概念对比 ### 视频编码 - **H.264 (AVC)**:兼容性最好,所有浏览器/设备都支持。视频服务的默认选择。 - **H.265 (HEVC)**:压缩率更高(同样画质体积减半),但浏览器支持不完整。适合 4K/8K 内容,需额外做兼容格式。 - **VP9**:Chrome 系浏览器原生支持的开源编码。 ### 浏览器缓存 vs CDN 缓存 - **浏览器缓存**:存在用户本地。解决方式:Ctrl+F5 强制刷新 / 无痕窗口。 - **CDN 缓存**:存在 CDN 节点上。解决方式:CDN 控制台刷新 / 改文件名重发。 ### CDN 三兄弟 - **刷新**:删除已有缓存,让下次请求回源拉新的。 - **预热**:主动把资源推到 CDN 节点存好。 - **封禁**:禁止 URL 访问(返回 403)。 ### 突发带宽 vs 源站压力 - **突发带宽**:带宽指标飙高。根因可能是 CDN 策略/攻击/正常流量。查带宽监控、X-Cache。 - **源站压力**:CPU/连接数飙高但带宽正常。根因通常是动态 API 被打爆。查请求次数、接口能缓存吗。 ### ffprobe 常见输出解读 - `codec_name=h264` → 正常,兼容性好 - `codec_name=hevc` → H.265,注意浏览器兼容 - 只有 audio 没有 video → 不是视频文件或转码出问题 - ffprobe 报错 → 文件损坏或格式不对
预览
编辑内容后实时预览...