OvenMediaEngine 0.21.0 常用运维命令与排障详解

OvenMediaEngine 0.21.0 运维命令面:日志双通道、端口核对、REST API 统计与流明细,附 8 个实测排障案例

OvenMediaEngineOvenMediaEngine流媒体DockerDocker Compose媒体服务器2026/10/30

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

三、前置条件

  1. OME 已按部署篇完成部署且常驻运行(docker compose ps 状态 Up);
  2. API 令牌已配置(本环境 q1w2e3r4),且你知道宿主映射端口;
  3. 本机有 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/vhostsvHost 列表{"message":"OK","response":["default"],"statusCode":200}
GET /v1/vhosts/defaultvHost 详情返回 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]

五、注意事项

  1. 令牌安全:AccessToken 是 API 唯一凭据,请勿入仓/入日志;对外暴露 8081 时建议叠加网络层访问控制。
  2. UDP 端口核对:ss -ltn 看不到 UDP,务必用 ss -lun;ICE 端口段映射缺失表现为「RTMP/LLHLS 正常但 WebRTC 黑屏」。
  3. 日志双通道:stdout 与日志文件内容不完全重合(见 4.1),故障复核以 /var/log/ovenmediaengine/ovenmediaengine.log 为准。
  4. 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.42c01f bypass,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)。

七、参考链接