上一轮收口时把三件事列为"仍需你知道的真实卡点":22 库超 SLA、RTMP 密钥未交付、WA/TG 无官方 API。 本轮逐个拆到底,结论是:其中两件的表述本身是错的——Telegram Bot API 与 WhatsApp Cloud API 都是官方接口, 实测出站 401/400(缺凭证,不是不可达);而"22 库超 SLA"里有 14 个根本没有上游可采。 真正需要造的是通路,不是等待授权。
先把事实摆出来,而不是继续按旧认知走人工点链:
| 接口 | 官方性 | 本轮实测 | 读法 |
|---|---|---|---|
| Telegram Bot API | 完全官方、免费 | api.telegram.org → 401 Unauthorized |
端点可达、协议正确,只差 bot token |
| WhatsApp Cloud API | Meta 官方 Graph API | graph.facebook.com → 190 Invalid OAuth access token |
端点可达,Meta 的错误体都正常返回,只差 access token + phone_id |
401 和 400 不是"打不通",恰恰是打通了而且对方在按规矩拒绝。把这两行贴在门禁里之后, "没有官方接口"这个前提就不再成立了。
im_bridge.pywa_send() 走 POST /v18.0/<phone_id>/messages,
tg_send() 走 POST /bot<token>/sendMessage,带限速(约 6 条/秒,远低于平台上限)与错误码归类。ilume-im-bridge.service 每 30 秒消费 im_task 里 st='ready' 的任务。
当前 120 条 WA + 30 条 TG 已全部有处置结果,没有一条静默挂着。deeplink 状态并保留可点链接,
日志里写明是 no_cred 还是 no_chat_id。/world/imb(实测 200 / 15ms),凭证只显后 4 位,落 im_cred.json 600 权限。api_ok 永久跳过;deeplink 6 小时内不重复记录;api_err 累计 3 次判硬失败,
避免常驻进程把日志刷爆或无限重试打平台接口。chat_id。
因此号码默认落深链;运营在 ib_chat 里登记 phone→chat_id 映射后立即走 API。131047 时若配了 wa_template 会自动改走模板;没配则如实报错,不假装成功。
一次配置,历史积压自动清空:cred set wa token=… phone_id=… 之后,
150 条里凡是有 chat_id 或有效号码的,下一轮 30 秒内全部自动发出,不需要任何人再点链接。
抖音 / 视频号 / 快手 / YouTube 的推流地址与密钥,只能由账号持有人在各自后台生成。 这不是代码问题,是账号归属问题——任何程序都替代不了。但"推流 0/12"的真实后果是 "没有任何一路视频在播",而这个后果可以独立解决。
live_channel.py用本地已有的 24 集节目源,切成 4 秒 HLS 分片,再按墙上时钟滚动改写播放列表。 每路 15 片 × 4 秒 = 60 秒一轮,观众任何时候进来都是"正在播",24 小时不断线。
| 指标 | 实测 |
|---|---|
| 频道数 | 12 路(主推/货架/碳合规/招标/撮合/成交/物流/征信/增长/供应链/标准/案例) |
| 单路体积 | 约 7.6 MB(480p / 900kbps / 15 片),12 路合计 91 MB |
| 构建耗时 | 单路 7.6–8.4 秒,12 路合计 94 秒(一次性) |
| 运行开销 | 零持续转码。每 4 秒只改一个 277 字节的文本,CPU ≈ 0 |
| 播放兼容 | iOS Safari 原生 m3u8;Chrome/Edge 走本地 hls.min.js(不依赖境外 CDN) |
static/live.html 的主播放器硬编码了 /live-media/hls/ep022/index.m3u8,
但该目录从未生成过——也就是说直播主页最显眼的那个播放器一直是黑的,页面本身却返回 200,
所以从来没进过任何红灯。本轮按同名补建 ep022,播放器立刻有源。
第一次接通后,连续三次请求拿到的 MEDIA-SEQUENCE 一模一样。文件 mtime 明明在前进。
原因是 open_file_cache max=10000 valid=30s 缓存的是文件描述符,而
os.replace() 原子替换换的是 inode——旧 fd 仍指向旧文件,nginx 在 30 秒有效期内一直吐旧列表。
直播列表 30 秒不变,就是卡死。
修法:用正则 location(优先级高于普通前缀)单独接管 *.m3u8,
open_file_cache off + Cache-Control: no-store;
分片 .ts 仍走原 location 保留 max-age=600(分片内容永不变化,缓存是纯赚)。
改完 MEDIA-SEQUENCE 逐秒递增。
200,播放列表实时滚动(门禁 G86 实测 8126235 → 8126236),
滚动服务 ilume-live-channel 开机自启。观看页 /live-wall.html(200 / 9.4 KB)。
livecast_hub 的 targets 会在数秒内自动开推,与轮播并行、互不冲突。
先纠正数字:实际是 16 个(14 个 STALE + 2 个 STALE3),不是 22。逐个查上游之后, 它们掉进四个性质完全不同的桶里:
| 类别 | 数量 | 日期 SLA 对它意味着什么 | 正确处理 |
|---|---|---|---|
| product 可售数据产品 | 302 新鲜 / 2 超期 | 超期=交付过期数据,真缺陷 | 必须补采,计入红灯 |
| pool 外呼客户池 | 6 | 只做触达名单,不进交付物 | 单列,报入库时间,不计红灯 |
| ops 运营库 | 9 | 最新记录=最后一笔业务时间,没有上游可采 | 单列,报闲置天数,不计红灯 |
| retired 已下架 | 1 | 不应参与任何健康统计 | 移出统计 |
把四类塞进一个红绿灯,结果是每次普查都有十几个"永远修不好"的红色, 真正该修的 product 超期被淹没。这不是数据问题,是度量问题。
① global_bids.db(招标):显示"超期 34 天"。查下去发现
fresh_hub 的时间列优先级里 updated_at 排第一,
而 global_bid_collector.py 只写 created_at、updated_at 永远为空。
数据是新的,度量取到的是空列。修法:采集器 INSERT 补写
datetime('now','localtime'),并回填存量 1,316 行。
② collector_data.db(采集框架):显示"超期 32 天"。查 collect_tasks
发现 216,222 条 done / 245,972 条 empty——它是已经消化完的任务队列,
不是数据产品。没有上游,也没有积压,只是没活干了。
global_bid_collector.py(UK TED + World Bank)和
trade_chain.py --fetch(UN Comtrade 贸易走廊)都在仓库里,也都能跑,
但从来没有被调度过。它们的数据于是停在最后一次手工运行的那天。
脚本没坏、上游没关,只是没人叫它起床——这类最容易被误判成"数据过期"。
| 动作 | 结果 |
|---|---|
| 手动跑一次招标采集 | 1,689 → 1,743 行(UK +10 / WB +60),采入 54 条新公告 |
| 纳入 root crontab | 451 → 453 行,均带 flock -n + timeout |
| 超时实测修正 | UN Comtrade 串行拉取要 10 分钟以上,初版 timeout 900 会把它腰斩在
export_products() 之前(表现为库文件变了、但 product 日期没变)→ 改 2400s |
| 完整跑通一次 | 16 分 28 秒跑完:采入 10,988 行,SCPI 192 / pairs 300 / products 15,
product.created_at 落到 2026-10-20 22:22 |
仍需单独处理、本轮未动的:82 个 EMPTY(行数 <60)与 20 个 DEAD(全表零行)。 它们不属于"超 SLA",属于空壳库清理,是另一件事,不在本轮范围内,也不该混进超期统计里。
| 编号 | 门禁 | 单测结果 |
|---|---|---|
| G86 | 直播频道:12 路分片齐备且在滚动 | PASS · 12 路,列表滚动 8126235→8126236,服务常驻 |
| G87 | IM 官方桥:队列无静默积压 | PASS · 150 条全部有处置结果 |
| G88 | 采集器调度:关键采集在 crontab 在册 | PASS · flock+timeout 齐备,看门狗守护 TED/Comtrade |
G88 是这轮最该长期保留的一条。它防的不是"数据过期",而是 "脚本存在 ≠ 有人调用"——这一个模式在本轮的 16 个红灯里占了 2 个。
| 事项 | 状态 | 为什么停在这里 |
|---|---|---|
| Platform simulcast(12 个平台真实推流) | 等密钥 | 推流地址与密钥只能由账号持有人后台生成。程序侧通路已就绪,密钥一到即自动开推 |
| WA/TG 真实外发 | 等凭证 | 适配器已打到官方接口(401/400 为证)。Telegram 另需 chat_id(Bot 不能凭手机号私聊) |
| 空壳库清理(82 EMPTY / 20 DEAD) | 未动 | 行数 <60 或全表零行。属于空壳库清理,不是「超 SLA」,是另一件事,不混进超期统计 |
日均来访 20–50 IP / dh_ask 为 0 | 业务问题 | 不是代码缺陷。有流量、有询盘才会产生 dh_ask,功能本身通 |
第一次全量跑(run_id=105)不是全绿,两个都记下来:
| 门禁 | 报什么 | 处理 |
|---|---|---|
| G16 | carbon-desk(+775) 交付包落后源库 |
真问题:源库在涨、交付包没重建。重建后单表 62,095 行(md5 5a7a0646…)、
全库 7 表 / 122,648 行(md5 b14f3754…) |
| G55 | 常驻服务 133 个,超过基线 131 | 本轮新增两个服务所致。按事实上调基线到 133,并把理由写进代码注释: 两者都是"没有它功能就不工作",不是拆分出来的进程;合并进 web 进程会把定时任务塞回请求路径 |
改完复跑 run_id=106:88 / 88 全绿,152 秒。
| 文件 | 改动 |
|---|---|
live_channel.py(新) | 轮播频道构建 / 播放列表滚动 / 状态。12 路 + ep022 补建 |
ilume-live-channel.service(新) | type=simple,4 秒一轮改写播放列表,开机自启 |
im_bridge.py(新) | TG Bot API / WA Cloud API 发送、凭证托管、出件队列、看板 |
ilume-im-bridge.service(新) | 30 秒一轮消费,开机自启 |
static/live-wall.html(新) | 12 路频道矩阵页,单播放器 + 频道切换 |
world_lib.py | 挂载 /world/imb(+198 字节,锚点唯一) |
fresh_hub.py | KIND 分类(product/pool/ops/retired),日期 SLA 只判 product |
regress_hub.py | 新增 G86/G87/G88,门禁 85→88 |
global_bid_collector.py | INSERT 补写 updated_at;存量回填 1,316 行 |
/etc/nginx/nginx.conf | 两个 server 块各加 m3u8 正则 location(open_file_cache off + no-store) |
| root crontab | +R261-GBID、+R261-TCHAIN(flock + timeout 2400),451→453 行 |
回滚点:live_channel.py.r261_pre、im_bridge.py.r261_pre、
world_lib.py.r261_imb_pre、fresh_hub.py.r261_pre、
regress_hub.py.r261_pre、global_bid_collector.py.r261_pre、
nginx.conf.r261_livebak、/root/crontab.r261.bak。