欢迎访问个人博客: https://www.crystalblog.xyz/
备用地址: https://wang-qz.gitee.io/crystal-blog/
(1) 使用MQ异步发送优惠券
(2) 使用MQ异步发送短信
(3) 使用MQ异步扣库存
总之, 将执行比较耗时的代码操作交给MQ异步实现接口.
为什么使用MQ
(1) 异步处理(多线程和MQ)
(2) 实现解耦
(3) 流量削峰 (MQ实现抗高并发)
有使用过MQ, 主要是做一些异步操作.
例如: 因为我们系统的接口是http协议, 属于同步接口, 如果接口执行业务比较耗时的情况下, 导致客户端一直阻塞等待, 容易引发客户端超时, 客户端发生超时之后就会触发重试策略, 重试过程中会导致数据的重复, 需要注意接口的幂等性问题. 其次是为了提高接口的响应速度, 可以将耗时的代码改成用MQ异步消费执行, 实现解耦.
(1) 多线程方式实现异步可能会消耗我们的CPU资源, 可能会影响到我们的业务线程, 发生CPU竞争的问题.
(2) MQ方式实现异步是完全解耦的, 适合用于大型互联网项目;
(3) 小的项目可以使用多线程实现异步, 大项目建议使用MQ实现异步.
(1) 生产背景
生产者投递消息的速率与我们消费者消费的速率完全不匹配.
(2) 生产者投递消息的速率 > 消费者消费的速率 , 导致我们消息会堆积在MQ服务器端, 没有及时的被消费, 就会产生消息堆积的问题.
(3) 注意, RabbitMQ消费者, 我们的消息消费如果成功, 消息会从服务端删除.
kafka或者RocketMQ消息如果成功的话, 消息是不会立即被删除.
(4) 解决办法:
提高消费者消费的速率(对我们的消费者实现集群)
消费者应该批量形式获取消息, 减少网络传输的次数.
绝大多数需求下, 例如异步发生短信, 发送优惠券是不需要解决消费顺序问题.
只有在特定业务场景下, 例如mysql与redis数据同步.
生产者在投递消息过程中, 同一个业务逻辑设定相同的消息key, 根据消息key计算hash投递到同一个broke, 同一个分区模型, 最终被同一个消费者消费.
不会, 因为我们的消息会持久化到我们硬盘中;
从多个维度分析,:
(1) MQ服务器端, 将消息刷盘存放到硬盘中.
(2) 从生产者端, 消息确认机制, 必须确认消息持久化到硬盘中 ,才能认为消息投递到MQ成功.
(3) 从消费者端, 消费者必须确保该消息消费成功.
(1) 生产者投递消息会将msg消息内容记录下来, 后期如果发生生产者投递消息失败, 可以根据日志记录实现补偿机制.
(2) 补偿机制, 就是获取到该msg日志消息内容实现重试.
RabbitMQ手动ack, 消费成功的情况下, 消息会从MQ服务器删除.
kafka手动提交offset, 消息还是在服务器端, 通过日志清理策略将该消息删除.