应用场景
尽可能的减少通过引入中间件的方式来解决问题。会让系统的整体复杂性变高。 拿 Redis 举例子: 引入了 Redis 就要考虑数据一致性的问题。 拿 MQ 举例子: 引入了 MQ 就要考虑 MQ 的生产,消费,服务端的各个问题。
- 生产者发消息没发出来怎么办、消费者没收到怎么办、服务端用着用着挂了怎么办。
- 流量削峰: 并发改并行
- 异步处理: 对外域系统. 对自身系统.
- 应用解耦: RPC 改 MQ
- 消息通讯:
- 本地缓存更新通知外域系统.
- 数据状态变更通知. (支付侧处理成功->佣金结算) (OFC 通知海外仓作业)
MQ 的消息模型
- 点对点 (管道)
- 发布订阅 (观察者)
常见八股问题
防止消息重复消费的解决方案
- 针对消息的唯一表示, 做数据库查询状态. (简单理解成乐观锁)
- 不选择缓存的背景: 终究是要失效的, 远程缓存或者本地缓存, 存在发版/TTL 的问题.
防止消息丢失
- 生产端丢了怎么办?
- 确认重试机制
- try cache + while
- 服务端丢了怎么办? 服务端挂了怎么办?
- MQ 自身提供了什么方案
- 如果没有提供,应该怎么不
- 消费端丢了怎么办?
- 处理一半停电了怎么办
顺序消费问题
- 状态机是否能够解决?
- 队列能否解决?
- 延迟消息能否使用?
- 往数据库根据排序写记录是否能够满足?
消息积压问题
- 针对当前的业务场景,评估合理的消息量,如果出现了和预估不符的数据量,是否考虑消费者挂了? 生产者一直在发重复消息?
- 是否是消费者消费的太慢?
- 业务代码写的是否规范? 有没有循环 IO?有没有死锁?有没有阻塞?
- 是否是生产者发的太快?
- 理论上,生产者的问题比较小。