高级发布订阅
可用性:完整版(Full)专属;精简版(Tiny)头文件中相关声明被剔除,误用会在编译期报错——这是一条明确的能力边界,而非运行期失败。
概述
高级发布订阅在普通发布 / 订阅之上提供缓存、丢包检测与历史恢复,适用于对数据完整性 要求较高的场景(晚加入的订阅者需要补齐历史、链路抖动需要自动重传丢失样本等)。
它解决的核心问题是普通发布 / 订阅「即发即忘」语义下的数据完整性缺口:
- 发布端缓存:发布者保留最近若干条样本,供晚加入的订阅者获取——解决「发布者先发、 订阅者后到」的历史空洞。
- 历史回放:订阅者加入时可一次性拉取发布端缓存的历史样本,补齐加入前的数据。
- 丢包检测与恢复:基于心跳检测样本丢失,并可自动恢复丢失的样本;丢失事件还可经 回调通知应用——解决链路抖动导致的样本丢失。
发布者与订阅者的句柄类型与普通版本相同,但需用对应的高级 API 发布 / 订阅;销毁时仍用 普通版本的 onepath_publisher_destroy / onepath_subscriber_destroy(见 发布与订阅)。
快速上手
c
/* 高级发布者:默认开启缓存(最多 10 条)+ 丢包检测 + 存在通告 */
onepath_publisher_t pub;
onepath_declare_advanced_publisher(s, &pub, "demo/adv/data", NULL);
onepath_advanced_publisher_put(pub, data, len);
/* 高级订阅者:加入时拉取历史 + 检测后续发布者 + 自动恢复 */
onepath_subscriber_t sub;
onepath_subscribe_advanced(s, &sub, "demo/adv/data", on_sample, NULL, NULL);
/* 可选:注册丢失通知回调 */
onepath_subscriber_on_miss(sub, on_miss, NULL);最佳实践:选项取舍
高级发布订阅的能力由发布端与订阅端两套选项共同决定,二者需配合才能达到预期语义:
| 目标语义 | 发布端选项 | 订阅端选项 |
|---|---|---|
| 晚加入订阅者补齐历史 | cache_enabled=1 + 足够的 cache_max_samples | history_enabled=1 |
| 检测后上线的发布者 | publisher_detection=1 | detect_late_publishers=1 |
| 自动重传链路抖动丢失样本 | miss_detection_enabled=1 + 缓存 | recovery_enabled=1 |
丢包检测依赖缓存与心跳
丢包检测与恢复依赖发布端缓存与心跳两端同时启用。若需要可靠的「不丢消息」语义, 发布端应保持 cache_enabled=1 并设置足够的 cache_max_samples,订阅端保持 recovery_enabled=1——缓存太小会丢掉本可恢复的历史,恢复关闭则只检测不补救。
默认值即开箱可用
两端选项的默认值(ONEPATH_ADVANCED_PUB_OPTS_DEFAULT / ONEPATH_ADVANCED_SUB_OPTS_DEFAULT)已开启全部能力。绝大多数场景下传 NULL(取默认) 即可获得完整的历史回放 + 丢包恢复语义;只有在内存敏感、需关闭某项能力时才显式传选项。
性能特征
高级能力带来的是可靠性收益,而非吞吐收益,且有一定代价:
- 发布端缓存会占用内存(与
cache_max_samples× 平均样本大小成正比);不限缓存 (cache_max_samples=0)在高速发布场景下会持续增长,需谨慎。 - 丢包检测的心跳与历史恢复的重传会引入额外带宽与往返;在追求极限吞吐的场景下, 可只保留
cache_enabled+history_enabled,关闭miss_detection_enabled/recovery_enabled以换取更低的协议开销。 - 历史回放在订阅者加入时一次性拉取全部缓存样本,缓存很大时会在加入瞬间产生突发 流量——若下游消费速率有限,需在应用层做限流或拆分。
限制与注意事项
- 高级发布订阅的可靠语义仅在发布端与订阅端两端同时启用对应能力时才成立:发布端关 闭缓存,订阅端的
history_enabled/recovery_enabled便无历史可取。 - 缓存容量有上限:发布端只保留最近
cache_max_samples条样本,更早的样本一旦被淘汰便 无法恢复——这不是「永久不丢」,而是「窗口内可靠」。 - 丢包检测与恢复依赖心跳间隔;心跳越短检测越快但开销越大,心跳越长越省开销但丢包感知 越慢。
- 样本回调收到的数据已深拷贝、归用户所有,用完须调用
onepath_sample_release(),见 内存管理。
API 参考
完整的函数签名、选项结构体与常量见 高级发布订阅 API。