目录
延迟消息
需求理解:
用户成功秒杀后,还没马上进行支付,一般支付时间是有限制的,如果用户15分钟后还没有进行支付,那么我们就发送消息,判断订单状态是否支付,未支付就回补真实库存,回补预库存,修改本地标识等操作
思路:
前面当用户秒杀成功后,会发送一条消息到MQ,然后消费者消费到这条消息后,就会马上通知用户秒杀成功。
这个时候,我们需要再写一个消费者类,同样是来消费这条消息的,只不过是延时发送消息。
理解下发送消息和消费消息的topic和tag
第1点: 这里是用户点击秒杀,然后往MQ发送一条数据,然后创建一个消费者来消费这条秒杀信息。
第2点: 这个是秒杀成功后,再发送一条秒杀结果的消息到MQ,然后消费者消费到这条消息之后,就通过websocket把秒杀结果发给用户。
目前两个消费者,一个属于CREATE_ORDER_GROUP消费组,一个属于CREATE_ORDER_SUCCESS_GROUP消费组
小细节:不管消费组属于哪个组,只要topic和tag能对应上,是可以消费同一个消息的。
第3点: 这个消费的是和上面第二点消费的是同个消息,只不过第2点是消费到消息马上就发送消息通知客户端,现在这个第3点是要延迟15分钟后,判断订单状态是否支付,未支付就回补真实库存,回补预库存,修改本地标识等操作
第2点和第3点都是消费者,属于不同的消费组,但都在消费同一个消息,然后用来做不同的业务处理。
第2点消费到消息后是马上通过websocket发送消息通知客户秒杀结果
第3点消费到消息是延迟十五分钟后发送消费,判断订单状态是否支付,未支付就回补真实库存,回补预库存,修改本地标识等操作
代码:
发送延迟消息
MessageBuilder的静态方法withPayload(T payload)新建一个消息构建器 再调用build()方法就可以将payload转换为一个Message对象
消息队列RocketMQ版服务器会存储所有成功发布的、所有类型的消息,最大存储时长为3天。如果消息存储时长超过3天,无论消息是否已被消费,都会被删除。建议配置监控报警实时监控消费进度,并根据报警信息人工介入处理。
测试结果:成功发送消息到MQ
消费延迟消息:
1、订单支付状态:
2、回补真实库存:
3、回补预库存:
需求: 回补redis中的预库存
思路: 把真实库存查出来,设置到redis中的预库存。
代码:
4、修改本地标识:
需求: 回补真实库存后,需要修改本地标识,因为可能是集群服务,所以修改本地标识需要用广播模式,让每个服务都消费到这个要改本地标识的消息。
广播模式理解:
广播模式和生产者发送消息无关,还是正常发送消息,主要是在消费者这边,通过指定为广播模式,只要topic和tag一致,这个消费者都会把对应的消息进行消费。
比如有3条消息,有三个消费者,正常的默认的集群模式,就是一个消费者消费一条消息,如果把三个消费者都设置为消费模式,那么这个三个消费者每个都能消费到3条消息。
在定义 Consumer 时,通过 messageModel 这个属性指定消费模式,这里指定为 BROADCASTING,也就启动了广播模式的消费者
代码:
测试:
清除MQ数据:
1、把项目都先停掉
2、删除MQ存储数据的文件夹store里面的数据,删之前先把项目停掉,不然消费者组一直存在。
3、截断数据库表t_order_info和t_seckill_order,redis的可以清除也可以不用,只要不要登录的账号弄到重复下单(redis里面的数据)就行
RocketMQ的数据应该是存在c盘的这个地方,可以把这些数据都清除掉,用来测试MQ是否执行符合期望。
把store文件夹里面的这些东西都清除掉,这样MQ就会回到最原始的状态,不会有其他杂乱的数据。
期望结果:
我把发送延时时间设置为5分钟,就是我秒杀成功之后,过去五分钟,能把库存和预库存恢复,然后修改本地标识
5分钟后走这些代码
实际结果:
websocket成功连接
秒杀成功
数据库也正确,status也是0–未支付
五分钟后:
先走回补真实库存和预库存的方法,然后发送修改本地标识的消息
用广播模式消费
这时候真实库存和预库存都应该返回10,status也应该变成3–超时未支付
问题:
广播模式未生效
点击消费详情页看不了
没有找到这个消费组
解决方法:
消费组名改一下试试
等五分钟后结果
成功进行广播消费消息
代码没问题,但是管控台点着还有点毛病。不清楚
异步下单失败
需求1:
异步下单失败,需要回补预库存和修改本地标识。
trycatch异常后,后面的代码还会执行吗?
catch 中如果你没有再抛出异常 , 那么catch之后的代码是可以继续执行的 , 但是try中 , 报错的那一行代码之后一直到try结束为止的这一段代码 , 是不会再执行的
代码:
发送消息:
1、模拟秒杀失败
2、然后封装下秒杀失败的异常信息数据:code和msg
3、发送一条秒杀失败的消息到mq
消费消息:
4、创建一个消费消息的类,消费MQ中秒杀失败的消息
秒杀失败需要回补redis中的预库存以及修改本地标识(本地标识用来判断是否还有库存)
广播的消费者类是上面的需求写过的了。
测试:
Redis的预库存也恢复了,原本是10,减去1为9,秒杀失败后要回补回10。
需求2:
失败后通过websocket把消息通知给客户,然后跳转到商品列表页面。
这个代码和OrderNotifyMQListener这个是一样的,只不过code和msg改了下,但是没有实现跳转页面
socket.js 这里并没有按我的想法跳转,待研究。
提示是我自己写的msg,但是不明白为什么不提示跳转,秒杀成功就能有那个提示框,秒杀失败不知道为什么弹不出那个提示框,消费者的代码明明是一样的。