引入RabbitMQ秒杀接口异步化
2023-12-24 20:29:35
package com.java1234.miaosha.controller;
import com.java1234.miaosha.constant.Constant;
import com.java1234.miaosha.entity.MiaoShaMessage;
import com.java1234.miaosha.entity.Order;
import com.java1234.miaosha.entity.R;
import com.java1234.miaosha.entity.User;
import com.java1234.miaosha.rabbitmq.MQSender;
import com.java1234.miaosha.service.IMiaoShaGoodsService;
import com.java1234.miaosha.service.IMiaoShaService;
import com.java1234.miaosha.service.IOrderService;
import com.java1234.miaosha.util.RedisUtil;
import com.java1234.miaosha.util.StringUtil;
import com.java1234.miaosha.vo.MiaoShaGoodsVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* 秒杀控制器
*/
@RestController
@RequestMapping("/miaoSha")
public class MiaoShaController {
@Autowired
private RedisUtil redisUtil;
@Autowired
private IMiaoShaGoodsService miaoShaGoodsService;
@Autowired
private IMiaoShaService miaoShaService;
@Autowired
private IOrderService orderService;
@Autowired
private MQSender mqSender;
/**
* 执行秒杀
* @param request
* @param miaoShaGoodsId
* @return
*/
@RequestMapping("/exec")
public R exec(HttpServletRequest request, Integer miaoShaGoodsId,String verifyCode){
if(StringUtil.isEmpty(verifyCode)){
return R.error("验证码不能为空!");
}
//第一步:根据token得到用户user对象
String token = request.getHeader("token");
System.out.println("token:"+token);
User user = (User)redisUtil.get(Constant.REDIS_TOKEN_PREFIX, token);
System.out.println(user);
Object rnd=redisUtil.get(Constant.REDIS_VERIFYCODE_PREFIX, user.getId() + "," + miaoShaGoodsId);
if(rnd==null){
return R.error("验证码过期,请重新点击刷新验证码!");
}
if(!verifyCode.equals(String.valueOf(rnd))){
return R.error("验证码结果错误!");
}
MiaoShaMessage mm=new MiaoShaMessage();
mm.setUser(user);
mm.setMiaoShaGoodsId(miaoShaGoodsId);
mqSender.sendMiaoShaMessage(mm);
return R.ok("排队中");
// //第二步:判断库存是否足够
// MiaoShaGoodsVo miaoShaGoods = miaoShaGoodsService.findById(miaoShaGoodsId);
// Integer stock = miaoShaGoods.getStock();
// if(stock<=0){
// return R.error("库存不足!");
// }
//
// //第三步:判断用户是否重复秒杀
// HashMap map = new HashMap();
// map.put("user_id",user.getId());
// map.put("miaosha_goods_id",miaoShaGoodsId);
// Order orderE = orderService.findByUserIdAndMiaoShaGoodsId(map);
// if(orderE!=null){
// return R.error("您已经秒杀过此商品,不能重复秒杀");
// }
//
// //第四步:减库存,下订单,必须同一个事务
// String orderId = miaoShaService.miaoSha(user, miaoShaGoods);
// if(orderId!=null){
// Map<String,Object> resultMap=new HashMap<>();
// resultMap.put("orderId",orderId);
// return R.ok(resultMap);
// }else{
// return R.error("系统异常,请稍后重试!");
// }
}
}
package com.java1234.miaosha.controller;
import com.java1234.miaosha.constant.Constant;
import com.java1234.miaosha.entity.R;
import com.java1234.miaosha.entity.User;
import com.java1234.miaosha.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.imageio.ImageIO;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* 订单控制器
* @author java1234_小锋
* @site www.java1234.com
* @company Java知识分享网
* @create 2020-12-13 11:20
*/
@Controller
@RequestMapping("/verifyCode")
public class VerifyCodeController {
@Autowired
private RedisUtil redisUtil;
/**
* 返回验证码图片
* @param miaoShaGoodsId
* @return
*/
@RequestMapping(value = "/get",method = RequestMethod.GET)
public R get(HttpServletResponse response,String token, Integer miaoShaGoodsId){
System.out.println("token:"+token);
System.out.println("miaoShaGoodsId:"+miaoShaGoodsId);
/* String token = request.getParameter("token");
System.out.println("token:"+token);*/
Object o=redisUtil.get(Constant.REDIS_TOKEN_PREFIX,token);
if(o==null){
return null;
}
if(miaoShaGoodsId==null || miaoShaGoodsId <=0){
return null;
}
try {
BufferedImage image = this.createVerifyCodeImage(((User) o).getId(), miaoShaGoodsId);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image,"JPEG",out);
out.flush();
out.close();
return null;
}catch(Exception e){
e.printStackTrace();
return R.error("服务端异常");
}
}
private BufferedImage createVerifyCodeImage(Integer userId,Integer miaoShaGoodsId) {
int width=80;
int height=32;
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g=image.getGraphics();
g.setColor(new Color(0xDCDCDC));
g.fillRect(0,0,width,height);
g.setColor(Color.black);
g.drawRect(0,0,width-1,height-1);
Random rdm=new Random();
for(int i=0;i<50;i++){
int x=rdm.nextInt(width);
int y=rdm.nextInt(height);
g.drawOval(x,y,0,0);
}
String verifyCode=createVerifyCode();
System.out.println("验证:"+verifyCode);
g.setColor(new Color(0,100,0));
g.setFont(new Font("Candara",Font.BOLD,24));
g.drawString(verifyCode+"=",8,24);
g.dispose();
int rnd=calc(verifyCode);
System.out.println("rnd:"+rnd);
redisUtil.set(Constant.REDIS_VERIFYCODE_PREFIX,userId+","+miaoShaGoodsId,rnd,Constant.REDIS_VERIFYCODE_EXPIRE);
return image;
}
public static void main(String[] args) {
String verifyCode=createVerifyCode();
System.out.println(calc(verifyCode));
}
/**
* 计算表达式
* @param exp
* @return
*/
private static int calc(String exp) {
ScriptEngineManager manager=new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
try {
return (int) engine.eval(exp);
} catch (ScriptException e) {
e.printStackTrace();
return 0;
}
}
private static char[] ops=new char[]{'+','-'};
/**
* + - 运算
* @return
*/
private static String createVerifyCode() {
Random rdm=new Random();
int num1=rdm.nextInt(10);
int num2=rdm.nextInt(10);
char op1=ops[rdm.nextInt(2)];
System.out.println("op1:"+op1);
String exp=num1+String.valueOf(op1)+num2;
System.out.println("exp:"+exp);
return exp;
}
}
package com.java1234.miaosha.rabbitmq;
import com.java1234.miaosha.config.MQConfig;
import com.java1234.miaosha.entity.MiaoShaMessage;
import com.java1234.miaosha.entity.Order;
import com.java1234.miaosha.entity.R;
import com.java1234.miaosha.entity.User;
import com.java1234.miaosha.service.IMiaoShaGoodsService;
import com.java1234.miaosha.service.IMiaoShaService;
import com.java1234.miaosha.service.IOrderService;
import com.java1234.miaosha.util.BeanUtil;
import com.java1234.miaosha.util.RedisUtil;
import com.java1234.miaosha.vo.MiaoShaGoodsVo;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@Service
public class MQReceiver {
@Autowired
private RedisUtil redisUtil;
@Autowired
private IMiaoShaGoodsService miaoShaGoodsService;
@Autowired
private IMiaoShaService miaoShaService;
@Autowired
private IOrderService orderService;
@RabbitListener(queues = MQConfig.MIAOSHA_QUEUE)
public void receiveMiaoShaMessage(String message){
MiaoShaMessage miaoShaMessage = BeanUtil.stringToBean(message, MiaoShaMessage.class);
System.out.println("receive message:"+miaoShaMessage);
User user = miaoShaMessage.getUser();
Integer miaoShaGoodsId=miaoShaMessage.getMiaoShaGoodsId();
//第二步:判断库存是否足够
MiaoShaGoodsVo miaoShaGoods = miaoShaGoodsService.findById(miaoShaGoodsId);
Integer stock = miaoShaGoods.getStock();
if(stock<=0){
System.out.println("库存不足");
return;
}
//第三步:判断用户是否重复秒杀
HashMap map = new HashMap();
map.put("user_id",user.getId());
map.put("miaosha_goods_id",miaoShaGoodsId);
Order orderE = orderService.findByUserIdAndMiaoShaGoodsId(map);
if(orderE!=null){
System.out.println("您已经秒杀过此商品,不能重复秒杀");
return;
}
//第四步:减库存,下订单,必须同一个事务
String orderId = miaoShaService.miaoSha(user, miaoShaGoods);
}
}
package com.java1234.miaosha.rabbitmq;
import com.java1234.miaosha.config.MQConfig;
import com.java1234.miaosha.entity.MiaoShaMessage;
import com.java1234.miaosha.util.BeanUtil;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MQSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void sendMiaoShaMessage(MiaoShaMessage miaoShaMessage){
String msg = BeanUtil.beanToString(miaoShaMessage);
System.out.println("send message:"+msg);
amqpTemplate.convertAndSend(MQConfig.MIAOSHA_QUEUE,msg);
}
}
package com.java1234.miaosha.util;
import com.alibaba.fastjson.JSON;
/**
* bean string转换工具类
* @author java1234_小锋
* @site www.java1234.com
* @company Java知识分享网
* @create 2020-12-28 15:10
*/
public class BeanUtil {
/**
* 将任意类型转换成字符串
* @param value
* @param <T>
* @return
*/
public static <T> String beanToString(T value) {
Class<?> clazz = value.getClass();
if(clazz == int.class || clazz == Integer.class) {
return value + "";
}else if(clazz == String.class) {
return (String)value;
}else if(clazz == long.class || clazz == Long.class) {
return value + "";
}else {
return JSON.toJSONString(value);
}
}
/**
* 把一个字符串转换成bean对象
* @param str
* @param <T>
* @return
*/
public static <T> T stringToBean(String str, Class<T> clazz) {
if(str == null || str.length() <= 0 || clazz == null) {
return null;
}
if(clazz == int.class || clazz == Integer.class) {
return (T)Integer.valueOf(str);
}else if(clazz == String.class) {
return (T)str;
}else if(clazz == long.class || clazz == Long.class) {
return (T)Long.valueOf(str);
}else {
return JSON.toJavaObject(JSON.parseObject(str), clazz);
}
}
}
文章来源:https://blog.csdn.net/m0_68935893/article/details/135185902
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!