当前位置: 首页 > news >正文

抽奖系统-抽奖

文章目录

  • 前言
  • 抽奖异步接口实现-MQ生产者
  • 抽奖异步接口实现-MQ消费者
  • 消费者& 校验抽奖请求
  • 扭转状态思路
  • 状态扭转实现1
  • 扭转状态实现2
  • 扭转状态实现3
  • 扭转状态实现4
  • 保存中奖记录
  • 发送消息服务
  • 抽奖回滚实现
  • 测试
    • 正向流程
    • 消息回滚
    • 消息重发
  • 查询中奖记录
  • 查询中奖记录
  • 前端
  • 项目部署
  • 总结


前言

抽奖异步接口实现-MQ生产者

在这里插入图片描述

[请求] /draw-prize POST
{"winnerList":[{"userId":15,"userName":"胡⼀博"},{"userId":21,"userName":"范闲"}],"activityId":23,"prizeId":13,"prizeTiers":"FIRST_PRIZE","winningTime":"2024-05-21T11:55:10.000Z"
}
[响应] 
{"code": 200,"data": true,"msg": ""}

在这里插入图片描述
controller
在这里插入图片描述

service:把数据丢给MQ
在这里插入图片描述
测试
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

抽奖异步接口实现-MQ消费者

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

消费者& 校验抽奖请求

mapper
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扭转状态思路

一个奖品的数量是一次性全部抽取完的,而且一个人只能抽取一个奖品
人员数量大于奖品数量
在这里插入图片描述
在这里插入图片描述

状态扭转实现1

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扭转状态实现2

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

扭转状态实现3

活动状态改变
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
奖品状态改变
在这里插入图片描述

在这里插入图片描述

活动状态扭转
在这里插入图片描述
在这里插入图片描述
保存为缓存

扭转状态实现4

然后开始测试
在这里插入图片描述

在这里插入图片描述

然后就是并没有问题

保存中奖记录

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
测试OK

发送消息服务

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>
</dependency>

还有配置

## 邮件 ##
spring.mail.host=smtp.qq.com
spring.mail.username=发送者邮箱
# 你的授权码:邮箱设置-》第三⽅服务-》开启IMAP/SMTP服务-》获取授权码
spring.mail.password=你的授权码
spring.mail.default-encoding=UTF-8

然后是配置一个util

@Component
@Slf4j
public class MailUtil {private static final Logger logger =LoggerFactory.getLogger(MailUtil.class);@Value(value = "${spring.mail.username}")private String from;@Autowiredprivate JavaMailSender mailSender;public Boolean sendSampleMail(String to, String subject, String context) {SimpleMailMessage message = new SimpleMailMessage();message.setFrom(from);message.setTo(to);message.setSubject(subject);message.setText(context);try {mailSender.send(message);} catch (Exception e) {logger.error("向{}发送邮件失败!", to, e);return false;}return true;}
}

然后开始实现中奖的发送信息
我们异步发送邮箱和手机短信,由于手机号短信我用不了,所以我们就发两次模拟异步发消息
异步发消息的意思就是多线程的意思
配置线程池

## 线程池 ##
async.executor.thread.core_pool_size=10
async.executor.thread.max_pool_size=20
async.executor.thread.queue_capacity=20
async.executor.thread.name.prefix=async-service-

然后是线程池配置类

@Configuration
@EnableAsync//启动异步的方法
@Data
public class ExecutorConfig {@Value("${async.executor.thread.core_pool_size}")private int corePoolSize;@Value("${async.executor.thread.max_pool_size}")private int maxPoolSize;@Value("${async.executor.thread.queue_capacity}")private int queueCapacity;@Value("${async.executor.thread.name.prefix}")private String namePrefix;@Bean(name = "asyncServiceExecutor")public ThreadPoolTaskExecutor asyncServiceExecutor(){ThreadPoolTaskExecutor threadPoolTaskExecutor = newThreadPoolTaskExecutor();threadPoolTaskExecutor.setCorePoolSize(corePoolSize);threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);threadPoolTaskExecutor.setQueueCapacity(queueCapacity);threadPoolTaskExecutor.setKeepAliveSeconds(3);threadPoolTaskExecutor.setThreadNamePrefix(namePrefix);// rejection-policy:当pool已经达到max size的时候,如何处理新任务// CALLER_RUNS:不在新线程中执⾏任务,⽽是由调⽤者所在的线程来执⾏threadPoolTaskExecutor.setRejectedExecutionHandler(newThreadPoolExecutor.AbortPolicy());//加载threadPoolTaskExecutor.initialize();return threadPoolTaskExecutor;}
}

在这里插入图片描述

抽奖回滚实现

就是发送了异常后,要把以前的处理给恢复,比如扭转回去状态
然后就是保存中奖者名单的时候,要删去保存的名单
发送短信那里,没有对数据库进行修改,所以不要抛出异常和回滚
因为状态扭转的时候是用了事务的
所以奖品和人员的状态要么一起变,要么一起不变,如果变了的话,就要回滚状态了

奖品状态是否需要改变:
在这里插入图片描述

在这里插入图片描述

改变奖品状态

在这里插入图片描述在这里插入图片描述

中奖状态是否需要改变:
在这里插入图片描述
在这里插入图片描述
回滚中奖者信息
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后就是开始测试了

测试

正向流程

在这里插入图片描述
在这里插入图片描述
修改一下,这里的校验参数这里不用抛异常,这里只是为了检验参数而已,看要不要进行抽奖,防止多来几次请求,如果传进来的参数不对,那么就false
真正要抛异常的地方是那些对数据库进行修改的地方
这样对参数进行校验,也可以保证幂等性了,多次请求结果一样,不然第二次一样请求就报错了,然后回滚,相当于都白干了

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

消息回滚

在这里插入图片描述
直接new一个异常

在这里插入图片描述
在这里插入图片描述
什么都没有
在这里插入图片描述
而且有六个异常,说明重发了
注意邮箱的配置也要修改一下,运行不起来了
在这里插入图片描述

消息重发

在这里插入图片描述
就是定义死信队列

就是定义死信队列,交换机,和对应的绑定
然后是普通队列把消息转到死信队列
在这里插入图片描述

在这里插入图片描述

这样死信队列就有数据了

注意记得把原来的额普通队列删了,因为属性改变了
在这里插入图片描述

然后死信队列就有消息了,然后给死信队列也搞一个消费者,进行相关处理之后,比如把这种不能处理的消息存入数据库,或者干嘛,这里我们就不处理了,最后重新发给普通队列的,让普通队列的消费者消化

在这里插入图片描述

查询中奖记录

在这里插入图片描述

[请求] /winning-records/show POST
{"activityId":23
}
[响应] 
{"code": 200,"data": [{"winnerId": 15,"winnerName": "胡⼀博","prizeName": "华为⼿机","prizeTier": "⼀等奖","winningTime": "2024-05-21T11:55:10.000+00:00"},{"winnerId": 21,"winnerName": "范闲","prizeName": "华为⼿机","prizeTier": "⼀等奖","winningTime": "2024-05-21T11:55:10.000+00:00"}],"msg": ""
}

查询中奖记录

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

前端

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

注意改一下对应的属性,因为和前端对不上
在这里插入图片描述

比如在这里

在这里插入图片描述
就会直接跳过这个抽取的界面
然后就是修修改改代码
注意不同方法可以换行,便于调试

然后就可以成功了

项目部署

记得改mysql密码,图片地址,redis端口等等

然后就是打包的时候过滤掉测试部分
在这里插入图片描述
<maven.test.skip>true</maven.test.skip>这个就表示打包跳过测试

执行sql脚本
mysql -u root -p

source 绝对路径下的sql文件

在这里插入图片描述

总结

http://www.xdnf.cn/news/496585.html

相关文章:

  • uni-app小程序登录后…
  • 数据分析_Python
  • arduino平台读取鼠标光电传感器
  • MATLAB学习笔记(七):MATLAB建模城市的雨季防洪排污的问题
  • Elasticsearch 性能优化面试宝典
  • LabVIEW声音与振动测量分析
  • STM32实战指南:SG90舵机控制原理与代码详解
  • Qt与Hid设备通信
  • 392. Is Subsequence
  • 天拓四方锂电池卷绕机 PLC 物联网解决方案
  • 从零开始认识 Node.js:异步非阻塞的魅力
  • Go语言 GORM框架 使用指南
  • c/c++的opencv模糊
  • exit耗时高
  • PYTHON训练营DAY28
  • AMD Vivado™ 设计套件生成加密比特流和加密密钥
  • 【React中虚拟DOM与Diff算法详解】
  • 免费商用字体下载
  • STM32IIC协议基础及Cube配置
  • 创建react工程并集成tailwindcss
  • C++(20): 文件输入输出库 —— <fstream>
  • Pytorch实现常用代码笔记
  • 从代码学习深度学习 - 词嵌入(word2vec)PyTorch版
  • 05、基础入门-SpringBoot-HelloWorld
  • 页面上如何显示特殊字符、Unicode字符?
  • 【001】RenPy打包安卓apk 流程源码级别分析
  • ProfibusDP主站转modbusTCP网关与ABB电机保护器数据交互
  • LangGraph(四)——加入人机交互控制
  • history模式:让URL更美观
  • 26、思维链Chain-of-Thought(CoT)论文笔记