订阅是「一次登记、长期推送」:平台说「我对目录变化感兴趣」,设备就一直推。 但它有有效期,过期不续设备就静悄悄地停了——这是最难查的一类故障。
前面的查询都是「问一次得一次」,这一节讲「问一次得很多次」。 它解决的是「变化要跟上」的问题:轮询太慢,推送才实时。 代价是「状态要维护」——订阅会过期,通知会丢。
一、三类订阅
目录订阅:设备上下线、通道增删,推上来。这是级联对接最常用的一类。
报警订阅:有警情就推。它和报警流程是配套的——不订阅,设备不知道往哪推。
位置订阅:移动设备(车载、单兵)的位置变化。这一类周期短、频率高,有效期通常只有几分钟。
三类的机制一样,只是「推什么」不同:
都是 SUBSCRIBE 登记、NOTIFY 推送、到期前再 SUBSCRIBE 续。
位置订阅的有效期短,是因为位置一直在变,长订阅没有意义,还会浪费推送。
二、过期不续,它不告诉你
订阅过期是「静默」的:设备不会发一条「我不推了」,它只是不推了。 这是最难查的地方:平台以为还在收,设备以为已经过期,两边都安静,谁都不报错。 表现就是「前几天好好的,今天目录不更新了」,重启一下又好了——因为重启会重新订阅。 所以续订必须做在定时任务里,而且要比「过期」提前很多: 常见做法是用掉三分之二就续,留三分之一的时间做重试余量。 这个比例是经验值:一次失败还能再来两次,网络抖一下不至于过期。
三、通知丢了怎么办
推送是会丢的,尤其在 UDP 上。丢了之后平台和设备的状态就不一致了,而且不会自己恢复。 只靠推的方案,丢一条就永久不一致——因为后面不会再有「重发」的机会。 所以工业做法是「推+定时全量」:靠推来保实时,靠定时全量来保正确。 两条腿走路,缺一条都会在某个时刻翻车。 「定时全量」的周期取多长,取决于「能容忍多久的不一致」。 目录变化不频繁的,几小时一次就够;要求高的,半小时一次。 只靠拉(轮询)也不是不行,但延迟大、请求多,而且「变化」这种事,轮询天生就慢一拍。
四、动手 Demo:订阅一次管多久,过期了会怎样
列四类订阅的有效期,看它们的使用方式。 再算「三分之二就续」的报文量和丢通知的应对方案。
life = 3600
renew = life * 2 // 3
print("有效期", life, "秒,每", renew, "秒续一次")
print("千路每小时续订", 3600 // renew * 1000, "次")
for name, ok in (("只靠推", False), ("推+定时全量", True),
("只靠拉", False)):
print(name, "能自愈" if ok else "不一致会留着")
实跑输出:
--------------------------------------------------------------------
订阅一次管多久,过期了会怎样
--------------------------------------------------------------------
**订阅是「一次登记、长期推送」**:**平台说「我对目录变化感兴趣」,设备就一直推。**
**它解决的是「查询要反复问」的问题**——**问一次只得到当下,推一次能跟上变化。**
类型 常见有效期 效果
---------------------------------------------------
**目录订阅** **3600 秒** **变化实时到**
**报警订阅** **3600 秒** **变化实时到**
**位置订阅** **300 秒** **变化实时到**
**不订阅** **—** **只能反复查**
**订阅是有有效期的**,**过期不续,设备就不推了,而且「不会告诉你它停了」。**
**这是最难查的一类故障:**
**平台以为还在收,设备以为已经过期,两边都安静。**
**所以续订必须做在心跳逻辑里**:
有效期 3600 秒,按「用掉三分之二就续」算,每 2400 秒续一次
千路设备每小时续订 1000 次、约 0.4 MB
**量很小,但漏一次就丢一片通知。**
**所以续订要比「过期」提前很多**,**不能等到最后一秒——网络一抖就过期了。**
**「三分之二」这个比例是经验值**:**留三分之一的时间做重试余量,一次失败还能再来两次。**
**还有一个设计问题:通知丢了怎么办**
做法 代价 效果
--------------------------------------------------------------------
**只靠推** **零成本** **丢了就永久不一致**
**推+定时全量** **带宽一次性变大** **能自愈,推荐**
**只靠拉** **延迟大、请求多** **永远一致但很笨**
**第二行是标准答案**:**靠推来保实时,靠定时全量来保正确。**
**两条腿走路,缺一条都会在某个时刻翻车。**
2400 秒续一次,也就是四十分钟, 一千路每小时续一千次、总共不到半兆——所以「续订会不会太频繁」这个担心是多余的。 真正的问题是「漏一次就丢一片通知」,而漏一次的概率并不低: 网络抖动、平台重启、设备重启,都会漏。 那张三行表是这一节的核心结论:只靠推,丢了就永久不一致;只靠拉,永远一致但慢一拍。 推+定时全量,既有实时性又能自愈。 「定时全量」听着笨,但它是唯一不需要「保证送达」就能自愈的方案—— 因为下一次全量会把所有差异抹平。
30 秒实验
- 算一下:有效期一小时、三分之二就续,多久续一次?(2400 秒)
- 想一下:订阅过期时设备会通知吗?(不会,是静默的)
- 想一下:只靠推的方案为什么会永久不一致?
常见误区
- 以为「订阅一次永久有效」。 有有效期,过期静默失效。
- 以为「通知一定能送到」。 UDP 上会丢,必须靠全量校准兜底。
- 以为「续订很费流量」。 千路每小时不到半兆。
自测三问(点开对答案)
1. 三类订阅分别是什么? —— **目录订阅、报警订阅、位置订阅**。 2. 为什么续订要「用掉三分之二就续」? —— **留三分之一做重试余量**,**一次失败还能再来两次。** 3. 「推+定时全量」为什么能自愈? —— **下一次全量会把所有差异抹平**,**不依赖「每条通知都送达」。**最后一节讲对讲:只有 64 kbps,却比视频更挑网络。
- ☐ (本节完,下一节 10.08.12 语音广播和语音对讲)