OvenMediaEngine 0.21.0 常用运维命令与排障详解
OvenMediaEngine 0.21.0 运维命令面:日志双通道、端口核对、REST API 统计与流明细,附 8 个实测排障案例
OvenMediaEngine 0.21.0 常用运维命令与排障详解
目标:给已部署 OvenMediaEngine(OME)v0.21.0 的运维者一套「看得见、查得准」的命令面——日志怎么看、端口怎么核、REST API 怎么查、配置变更怎么生效,并沉淀 8 个本站实测复现过的真实故障案例(现象 → 定位 → 解决 → 验证)。全部命令与回显均来自 Ubuntu 24.04 服务器实测。
一、环境信息
| 项 | 值 |
|---|---|
| 操作系统 | Ubuntu 24.04(x86_64,内核 7.0.0-38-generic) |
| OME 版本 | v0.21.0(2026-08-13 发布,部署细节见部署篇) |
| 部署形态 | Docker Compose(栈名 ovenmediaengine-0.21.0-stack,专用网络 ovenmediaengine-0.21.0-net) |
| 端口映射 | RTMP 8160 / SRT 8161(UDP) / 信令+HLS 8162 / API 8163 / ICE 8164(UDP) / ICE-TCP 8165 |
| API 令牌 | q1w2e3r4(配置于 Server/Managers/API/AccessToken) |
| 验证时间 | 2026-10-29 |
二、工具概览
OME 不自带管理 CLI,运维面由四部分组成:
| 工具 | 用途 | 典型命令 |
|---|---|---|
| 引擎日志(stdout + 日志文件) | 启动校验、建流/断流、W/E 级故障 | docker logs -f ...、容器内 /var/log/ovenmediaengine/ovenmediaengine.log |
| REST API(8163) | 运行统计、vHost/应用/流明细 | curl -H "authorization: Basic base64(token)" http://127.0.0.1:8163/v1/... |
| 端口与协议探测 | 监听核对、播放列表健康检查 | ss -ltn、curl -s -o /dev/null -w '%{http_code}' .../llhls.m3u8 |
| Compose 生命周期 | 重启生效、栈管理 | docker compose ps/restart/logs |
三、前置条件
- OME 已按部署篇完成部署且常驻运行(
docker compose ps状态 Up); - API 令牌已配置(本环境
q1w2e3r4),且你知道宿主映射端口; - 本机有
curl、ss、jq(可选)。
四、各工具详解
4.1 服务状态与日志
# 栈状态
docker compose ps --format '{{.Name}} {{.Status}}'
实测回显:
ovenmediaengine-0.21.0-app Up 17 minutes
ovenmediaengine-0.21.0-publisher Up 16 minutes
ovenmediaengine-0.21.0-srt-publisher Up 17 minutes
# stdout 日志:启动横幅、建流、Publisher 注册
docker logs -f ovenmediaengine-0.21.0-app
# 引擎日志文件:完整的 W/E 级详情(部分警告只在文件里)
docker exec ovenmediaengine-0.21.0-app tail -f /var/log/ovenmediaengine/ovenmediaengine.log
日志行格式:[时间戳] [级别 I/W/E] [线程] 组件 | 源文件:行号 | 内容。分级过滤(在日志文件上):
docker exec ovenmediaengine-0.21.0-app sh -c \
"grep -E '\] E \[' /var/log/ovenmediaengine/ovenmediaengine.log | tail -20" # 全部 E 级
docker exec ovenmediaengine-0.21.0-app sh -c \
"grep -E 'disabled by configuration' /var/log/ovenmediaengine/ovenmediaengine.log" # 组件禁用清单
实测禁用清单回显(默认配置下,W 级):
ThumbnailPublisher is disabled by configuration
HLSv3 Publisher is disabled by configuration
SRTPublisher is disabled by configuration
MPEGTSProvider is disabled by configuration
⚠️
docker logs(stdout)与日志文件内容不完全一致:stdout 偏向启动横幅与建流事件,disabled by configuration、Empty <AccessToken>等校验类警告只进日志文件。排障先查文件。
4.2 端口与协议健康检查
# TCP 监听核对(宿主映射侧)
ss -ltn | grep -E ':(8160|8162|8163|8165)\b'
# UDP 监听核对(SRT 推流 8161 / WebRTC ICE 8164)
ss -lun | grep -E ':(8161|8164)\b'
实测回显(TCP 节选):
LISTEN 0 4096 0.0.0.0:8160 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8162 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8163 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8165 0.0.0.0:*
# 分发健康探测(200=流在播,404=流不存在或 Publisher 未启用)
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8162/app/stream/llhls.m3u8 # LLHLS 默认列表
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8162/app/stream/master.m3u8 # 自定义 ABR 列表
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8162/app/stream/ts:playlist.m3u8 # HLSv3(TS)
💡 URL 规则:
llhls.m3u8/master.m3u8为 fMP4 打包;ts:前缀(如ts:playlist.m3u8)为 HLSv3 的 TS 打包,同一端口按文件名前缀分流。
4.3 REST API 运维面
认证(三形态实测,token=q1w2e3r4):
T=$(printf 'q1w2e3r4' | base64)
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8163/v1/stats/current # 不带凭据 → 401
curl -s -o /dev/null -w '%{http_code}\n' -H "authorization: Basic $(printf 'q1w2e3r4:' | base64)" http://127.0.0.1:8163/v1/stats/current # 带冒号 → 401
curl -s -o /dev/null -w '%{http_code}\n' -H "authorization: Basic $T" http://127.0.0.1:8163/v1/stats/current # token 原样 → 200
401 响应体实测:
{"message":"[HTTP] Authorization header is required to call API (401)","statusCode":401}
⚠️ 认证写法与惯例不同:Basic 的用户名部分是令牌原样,不带
:。带冒号(会被解析为「用户名+空密码」)同样 401。
常用端点速查(均实测 200):
| 端点 | 作用 | 实测回显要点 |
|---|---|---|
GET /v1/vhosts | vHost 列表 | {"message":"OK","response":["default"],"statusCode":200} |
GET /v1/vhosts/default | vHost 详情 | 返回 Host/应用配置摘要 |
GET /v1/vhosts/default/apps | 应用列表 | ["app"] |
GET /v1/vhosts/default/apps/app | 应用详情 | 输出 Profile/Provider 配置 |
GET /v1/vhosts/default/apps/app/streams | 流列表 | ["stream_srt","stream"](实测两路并发推流) |
GET /v1/vhosts/default/apps/app/streams/stream | 流明细 | 输入/输出轨道,见下 |
GET /v1/stats/current | 全局实时统计 | 见下 |
流明细(排障利器)——/v1/vhosts/default/apps/app/streams/stream 实测节选:
outputs.tracks:
id=0 Video bypass=True codec=H264 1280x720 ← bypass 直通档
id=1 Video bypass=False codec=H264 1280x720 ← video_720 重编码档
id=2 Audio bypass=True codec=AAC
id=3 Audio bypass=False codec=OPUS ← WebRTC 用 Opus 音轨
id=4 Data
(一路推流经 ABR 配置后产出双视频档 + 双音频轨,bypass 标记与播放列表档位一一对应。)
实时统计——/v1/stats/current 实测回显:
{
"message": "OK",
"response": {
"avgThroughputIn": 2284199,
"avgThroughputOut": 5880,
"connections": {
"file": 0, "hlsv3": 16, "llhls": 16,
"ovt": 0, "push": 0, "srt": 0, "thumbnail": 0, "webrtc": 0
},
"createdTime": "2026-10-29T14:55:52.346+00:00",
"lastThroughputIn": 292092,
"maxTotalConnections": 32,
"totalBytesIn": 4342388,
"totalConnections": 32
},
"statusCode": 200
}
(connections 按分发器分类计数——实测用 curl 周期拉取播放列表产生了 hlsv3:16、llhls:16 的会话数,正好验证了 HLSv3 与 LLHLS 两个 Publisher 同时在工作;吞吐单位为 bps。)
⚠️ v0.21 的统计端点路径与旧版教程有差异:实测
/v1/stats/systems返回 404(该资源不在 v1 树中),以/v1/stats/current为准;遇到 404 时先用/v1/vhosts自顶向下探路。
4.4 配置变更生效路径
OME 无热加载,配置变更走「改文件 → 重启 → 验证」三步(实测路径):
vim /opt/ovenmediaengine-compose/Server.xml # ① 改配置
docker compose restart # ② 重启生效(实测无需重建容器)
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8162/app/stream/ts:playlist.m3u8 # ③ 验证新配置
实测案例:给 Bind/Publishers 增加 <HLS><Port>3333</Port></HLS> 并重启后,ts:playlist.m3u8 从 404 变 200;日志文件中 HLSv3 Publisher is disabled by configuration 警告不再出现。校验失败时进程拒绝启动,错误定位见 6.1/6.2。
4.5 推流端自检
# RTMP 推流(ffmpeg 合成测试画面+正弦音;宿主装有 ffmpeg 可直接推宿主端口)
ffmpeg -re -f lavfi -i "testsrc2=size=1280x720:rate=30" -f lavfi -i "sine=frequency=1000:sample_rate=48000" \
-c:v libx264 -preset veryfast -tune zerolatency -pix_fmt yuv420p -b:v 2000k -g 60 \
-c:a aac -b:a 128k -ac 2 -ar 48000 -f flv rtmp://127.0.0.1:8160/app/stream
# SRT 推流(streamid 三段式:vhost/app/stream,见 6.4)
ffmpeg -re -f lavfi -i "smptebars=size=1280x720:rate=30" -f lavfi -i "sine=frequency=440:sample_rate=48000" \
-c:v libx264 -preset veryfast -tune zerolatency -pix_fmt yuv420p -b:v 1500k -g 60 \
-c:a aac -b:a 128k -ac 2 -ar 48000 -f mpegts "srt://127.0.0.1:8161?streamid=default/app/stream_srt"
推流成功的双侧印证(OME 日志原文):
RTMPProvider | rtmp_provider.cpp:228 | A RTMP client has connected from <ClientSocket: ..., Connected, TCP, Nonblocking, ...>
MediaRouter | mediarouter_application.cpp:467 | [#default#app/stream(100)] Stream has been created
SrtProvider | srt_provider.cpp:202 | The SRT client has connected : <ClientSocket: ..., Connected, SRT, Nonblocking, ..., streamid: default/app/stream_srt> [349732745] [default/app/stream_srt]
五、注意事项
- 令牌安全:
AccessToken是 API 唯一凭据,请勿入仓/入日志;对外暴露 8081 时建议叠加网络层访问控制。 - UDP 端口核对:
ss -ltn看不到 UDP,务必用ss -lun;ICE 端口段映射缺失表现为「RTMP/LLHLS 正常但 WebRTC 黑屏」。 - 日志双通道:stdout 与日志文件内容不完全重合(见 4.1),故障复核以
/var/log/ovenmediaengine/ovenmediaengine.log为准。 - OriginMapStore 未启用时:Origin/Edge 只能静态配置,流位置无 Redis 登记簿,Edge 回源按配置文件写死;集群化改造前不要依赖动态寻址。
六、常见问题(排障实录,每例均为本环境实测复现)
6.1 API 端口不通:AccessToken 放错层级
- 现象:8163 拒连,进程启动即退出。
- 定位:日志文件
E级——
E [OvenMediaEngine:1] OvenMediaEngine | main.cpp:353 | An error occurred while load config: [Config] Unknown item found: Server.bind.managers.api.AccessToken in origin_conf/Server.xml
- 原因:把
<AccessToken>写进了Bind/Managers/API。v0.21 的 Bind 层只接受Port/WorkerCount。 - 解决:令牌移至
<Server>直属的<Managers><API>段,Bind内只留端口。 - 验证:重启后
curl -H "authorization: Basic $(printf 'q1w2e3r4' | base64)" http://127.0.0.1:8163/v1/vhosts返回 200。
6.2 API 启动失败:令牌缺失
- 现象:8163 无监听,stdout 无明显报错。
- 定位:日志文件
E级——
E [OvenMediaEngine:1] APIServer | api_server.cpp:56 | Empty <AccessToken> is not allowed
- 原因:启用了 API 监听但
<AccessToken>为空。Release 构建不允许空令牌(Debug 构建才有空令牌警告分支)。 - 解决:补
<AccessToken>q1w2e3r4</AccessToken>。 - 验证:重启后按 4.3 三形态实测,token 原样编码返回 200。
6.3 HLSv3 播放列表 404:Publisher 默认禁用
- 现象:
/app/stream/playlist.m3u8返回 404,而llhls.m3u8正常。 - 定位:日志文件——
W [OvenMediaEngine:1] HLS Publisher | hls_publisher.cpp:78 | HLSv3 Publisher is disabled by configuration
stdout 中对应组件只有 Trying to create HLS Publisher... 而无 has been started。
- 原因:默认
Bind/Publishers没有<HLS>绑定段,HLSv3(TS 打包)整组禁用。 - 解决:
Bind/Publishers下新增<HLS><Port>3333</Port><WorkerCount>1</WorkerCount></HLS>,重启。 - 验证:
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8162/app/stream/ts:playlist.m3u8返回 200,且/v1/stats/current的connections.hlsv3开始计数。
6.4 SRT 推流被拒:streamid 不是三段式
- 现象:ffmpeg 报
Connection to srt://...:9999?streamid=input://app/bad_stream failed: I/O error,OME 侧无流创建。 - 定位:日志文件——
I [SPSRT-s9999:52] SrtProvider | srt_provider.cpp:202 | The SRT client has connected : <..., streamid: input://app/bad_stream> [input://app/bad_stream]
E [SPSRT-s9999:52] SrtProvider | srt_provider.cpp:297 | Could not find vhost/app: #default#bad_stream
- 原因:v0.21 的 SRT streamid 已不带
input://前缀(与旧版教程相反),格式为{vhost}/{app}/{stream}三段式;两段式被错误解析(app/bad_stream被拆成未知应用与流名)。 - 解决:改用
streamid=default/app/stream_srt。 - 验证:OME 日志出现
[default/app/stream_srt]建流行,/v1/vhosts/default/apps/app/streams列表新增stream_srt。
6.5 播放列表 404 且流名可疑:请求了不存在的流
- 现象:
/app/nothing_here/llhls.m3u8返回 404。 - 定位:日志文件(与请求时间同秒)——
E [SPRtcSig-t3333:31] LLHLS Publisher | llhls_publisher.cpp:384 | Cannot find stream (#default#app/nothing_here)
[Request] GET http://127.0.0.1:8162/app/nothing_here/llhls.m3u8 (HTTP/1.1, Request Time: ...)
- 原因:URL 中的流名与推流端实际流名不一致(或流已断)。
- 解决:以
/v1/vhosts/default/apps/app/streams返回的列表为准修正 URL。 - 验证:改回真实流名后 200。
6.6 ABR 双档「不见了」:看错了播放列表
- 现象:配置双 Rendition 后
llhls.m3u8仍只有一个#EXT-X-STREAM-INF。 - 原因:
llhls.m3u8是引擎自动生成的默认单档列表;自定义多档列表访问<Playlist>/<FileName>指定的名字(本环境master.m3u8),两者并存。 - 验证:
master.m3u8返回双档(avc1.4d401f重编码 +avc1.42c01fbypass,BANDWIDTH 2158032/2149000,实测回显见部署篇);或直接查 API 流明细的双 Video 轨道(见 4.3)。
6.7 推流端 Name does not resolve:依赖服务重启时序
- 现象:OME 容器重启期间,推流端日志刷——
[tcp @ ...] Failed to resolve hostname ovenmediaengine-0.21.0-app: Name does not resolve
Error writing trailer of rtmp://ovenmediaengine-0.21.0-app:1935/app/stream: Broken pipe
- 原因:OME 容器停止后从专用网络摘除,内置 DNS 不再解析其主机名;推流端仍在重连。
- 解决:推流器使用自动重试策略(长驻容器 +
--restart unless-stopped,ffmpeg 断流自动重连),或 compose 中用depends_on表达依赖。OME 恢复后推流自动重建。 - 验证:OME 恢复后日志重现
Stream has been created,播放列表 200。
6.8 API 401:认证头写法错误
- 现象:携带了凭据仍返回
{"message":"[HTTP] Authorization header is required to call API (401)","statusCode":401}。 - 原因:v0.21 的 Basic 认证用户名为令牌原样(
base64("q1w2e3r4")),按惯例写成base64("q1w2e3r4:")(用户名+空密码)会被判为凭据缺失。 - 解决:
-H "authorization: Basic $(printf 'q1w2e3r4' | base64)",末尾不带冒号。 - 验证:三形态对照实测 401/401/200(见 4.3)。
七、参考链接
- 官方 REST API 文档:https://docs.ovenmediaengine.com/rest-api/v1
- 官方监控与日志文档:https://docs.ovenmediaengine.com/docs/ome/monitoring
- 本站系列文档:《OvenMediaEngine 介绍与选型指南》(能力总览)、《OvenMediaEngine 0.21.0 Docker Compose 部署指南》(端口映射与部署)、《OvenMediaEngine 0.21.0 配置参数详解》(Server.xml 逐段精讲)