作者:magicxie
场景:IoT 远程打印
痛点:下单即扣费、接口级故障、资源受限(8G 服务器 + 4G 消息中间件)
前言
很多人以为 IoT 就是"设备连上网,发个 HTTP 请求"。但在远程打印这种场景里,每一个接口请求背后,都是一台真实的打印机、一张纸、一笔钱。
尤其是当你只有 8G 服务器 + 4G 消息中间件 时,接口一旦出问题,不是 404,而是------用户投诉你多打了、多扣了、还不退款。
这篇文章,我会从原因、降级、熔断、限流、排队、小结六个方面,复盘一次典型的接口级故障。
一、故障原因:为什么接口会"突然不行了"
1️⃣ 资源天花板太明显
| 组件 | 规格 | 现实情况 |
|---|---|---|
| 应用服务器 | 8G | JVM + OS + MQ Client 抢占内存 |
| 消息中间件 | 4G | PageCache + 消息堆积 = OOM |
| 线程池 | 默认配置 | Tomcat 200,DB 50,MQ 30 |
在高并发打印请求下:
-
Full GC 频繁
-
MQ 吞吐骤降
-
接口 RT 从 100ms 飙升到 5s+
2️⃣ 同步调用链太长
一个"打印"接口,内部做了太多事:
HTTP 请求
→ 鉴权
→ 查余额
→ 创建订单
→ 扣费
→ 写 MQ
→ 等待打印机 ACK
→ 返回结果
问题只有一个:
只要其中一环慢,整个线程就卡死。
3️⃣ 设备侧重试放大问题
打印机断网、超时、信号差,会触发:
-
自动重连
-
自动重试
-
同一条任务多次提交
服务端看到的是:
同一个商户、同一台设备、短时间几十次请求。
4️⃣ 缺乏幂等保护
最致命的一点:
-
没有请求唯一 ID
-
没有 Redis 锁
-
没有数据库唯一约束
结果是:
接口挂了不可怕,可怕的是恢复后疯狂重复打印。
二、降级:先保命,再谈体验
在 IoT 打印系统里,降级不是"锦上添花",而是生存手段。
✅ 功能降级
| 功能 | 降级策略 |
|---|---|
| 实时余额校验 | 降级为"信用额度 + 异步对账" |
| 打印预览 | 关闭,使用默认模板 |
| 打印统计 | 返回缓存数据 |
| 推送通知 | 合并为定时推送 |
原则:
不直接影响"能不能打印"的功能,一律可降级。
✅ 数据降级
-
打印机状态:返回最后一次已知状态
-
订单详情:只返回
orderId + status -
查询接口:Redis / 本地缓存兜底
✅ 设备侧降级
-
打印机本地缓存任务
-
网络异常时进入离线模式
-
恢复后批量同步,而非实时请求
✅ 一句话总结降级:
宁可功能残缺,也不能让核心打印链路雪崩。
三、熔断:别让坏依赖拖死你
1️⃣ 哪些地方要熔断?
-
订单服务
-
支付 / 计费系统
-
MQ 发送接口
-
打印机回调接口
2️⃣ 熔断规则(实战可用)
失败率 > 50%
连续异常 > 20 次
平均 RT > 2s
3️⃣ 熔断后的行为
不要直接抛 500,而是:
{
"code": "SYSTEM_BUSY",
"message": "系统繁忙,已受理并排队"
}
✅ 关键点:
熔断不是拒绝业务,而是快速失败,保护系统。
四、限流:给系统装一道"闸门"
1️⃣ 三层限流体系
✅ 设备级
-
单台打印机 QPS ≤ 1
-
防止设备重试风暴
✅ 商户级
-
按商户 ID 限流
-
防止大客户压垮平台
✅ 接口级
| 接口 | 算法 |
|---|---|
| 创建订单 | 令牌桶 |
| 查询订单 | 漏桶 |
| 回调接口 | 滑动窗口 |
2️⃣ 限流阈值怎么定?
在 8G 环境下,一个相对安全的经验值:
Tomcat 线程:200
DB 连接池:50
MQ 消费并发:30
→ 订单接口 QPS ≈ 300~500
五、排队:IoT 打印系统的"灵魂设计"
所有"会花钱"的接口,必须先进队列。
✅ 请求阶段
HTTP 接口
→ 参数校验
→ 幂等校验
→ 写入 Redis Stream / Delay Queue
→ 立即返回 orderId + QUEUED
✅ MQ 优化(4G 很关键)
-
单 Topic,多 Consumer Group
-
消息体 < 64KB
-
设置 TTL + 死信队列
✅ 消费端背压
Consumer 根据以下指标调整速度:
-
线程池水位
-
打印机在线状态
-
MQ Lag
✅ 用户可感知的排队
{
"orderId": "P20260123456",
"status": "QUEUED",
"queuePosition": 8,
"estimatedTime": "约 90 秒"
}
✅ 价值:
-
用户可接受
-
系统压力可控
-
不丢单、不乱序
六、小结:架构师的几点思考
✅ 1. IoT ≠ Web 服务
| Web 服务 | IoT 打印 |
|---|---|
| 可回滚 | 不可回滚 |
| 延迟可接受 | 延迟必须可控 |
| 重试成本低 | 重试 = 真金白银 |
✅ 2. 小资源下的设计哲学
8G 内存 + 4G MQ 的核心原则:
-
少做同步
-
多做异步
-
所有高成本操作必须排队
-
所有写操作必须幂等
✅ 3. 故障应对优先级
熔断
↓
降级
↓
限流
↓
排队
而不是反过来。
✅ 4. 最后一句经验之谈
在 IoT 打印系统里,接口故障不可怕,可怕的是恢复之后,系统"自动帮你多打了几千张纸"。