可靠消息+最终一致性
# 可靠消息+最终一致性
## 绪论
> 以为之气那说过了, 高并发场景下不适合用seata分布式事务, 因此, 我们最终采取该方法(**可靠消息+最终一致性**)
## 延迟队列的使用场景
> 在当前项目中, 就有两个, 第一, 订单的自动取消, 第二, 库存的自动解锁
> 即过一段时间, 没有确认的订单自动取消, 过一段时间, 取消的订单自动解锁库存等.....

> 这里有一个细节, 就是解锁库存必须在取消订单后面, 否则, 一个要被取消的清单在解锁库存的时刻, 因为没有改变订单状态而错失取消订单的机会, 这非常的危险
## 最终一致性为什么使用延迟队列, 而不是定时任务?
1. 定时任务需要定期对数据库的大量数据进行扫描, 存在非常大的磁盘IO, 极度消耗系统资源
2. 定时任务存在一个致命的缺陷, 若30min一次扫描, 在29min的时候下订单, 实际上, 只有1min的下单时间, 凭空损失了29min, 这被称为时效性问题

## 复习
### 什么是TTL?
> TTL是消息的过期时间, TTL可以设置在发送消息的时候, 也可以作为队列的一个属性
> 如果在发送消息的时候设置TTL, 那么只有当前消息的过期时间是TTL, 其他都不是
> 如果在队列设置TTL, 那么这个队列所有的消息的过期时间都是TTL
> **我们不建议在发送消息的时候设置TTL, 因为, RabbitMQ采取的是惰性监测机制, 即只会监测第一个消息的过期时间, 如果第一个消息的过期时间远大于后面的消息, 后面的消息就会错误的被延长, 本来延迟10s 变成 延迟10min, 这个问题非常严重, 因此不建议发送消息的时候设置TTL**
### 什么是死信?(称为死信消息的三大场景)
1. 消息过期, 消息自动成为死信
2. 消息被NACK, 消息被拒绝确认应答, 消息成为死信
3. 队列溢出, 最老的消息成为死信
> 而死信交换机就是专门来接受死信消息的普通交换机
### 延迟队列的实现思路
> 延迟队列利用的是消息的TTL和死信交换机来实现的, 我们可以设置消息的过期时间, 让一个消息在延迟队列中放着, 没有任何人去消费他, 等到他过期之后, 转发到私信交换机进而到死信队列, 此刻, 由消费者去消费, 等待过期就是实验了延迟
#### 第一种

#### 第二种(惰性机制, 不推荐)

## 整体架构


## 搭建环境
1. 创建bitmall-mq模块, 并引入对应的依赖, 配置对应的yaml, 可以将之前的配置CV过来
2. 搭建整个消息体系
> 注意, 在搭建交换机, 队列等时, 一旦在RabbitMQ建立成功, 里面的属性不可变, 除非把RabbitMQ对应的东西给删掉, 因此, 一定要好好配置
> 如果将队列, 交换机等注入组件, 会自动在RabbitMQ创建
### 搭建误区
#### 为什么连接不上RabbitMQ
> 我这里的错误是队列参数的时候出现了错误, 主要是过期时间不可以设置为字符串, 必须是整形
#### 为什么成功连接, 但是没有队列或交换机
> 我们必须发一次请求, RabbitMQ才会创建, 否则就不创建