package cn.com.app.controller;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;
import cn.com.app.bean.MiaoshaUser;
import cn.com.app.rabbitmq.MQSender;
import cn.com.app.redis.AccessKey;
import cn.com.app.redis.GoodsKey;
import cn.com.app.redis.OrderKey;
import cn.com.app.redis.RedisLock;
import cn.com.app.redis.RedisLua;
import cn.com.app.redis.RedisService;
import cn.com.app.result.CodeMsg;
import cn.com.app.result.Result;
import cn.com.app.service.MiaoshaService;
import cn.com.app.service.MiaoshaUserService;
@Controller
@RequestMapping("/miaosha")
public class MiaoshaController implements InitializingBean {
@Autowired
private MiaoshaService miaoshaService;
@Autowired
private RedisService redisService;
@Autowired
private MiaoshaUserService userService;
@Autowired
private MQSender mQSender;
@Autowired
private JedisPool jedisPool;
//内存标记,减少redis访问
private HashMap<String, Boolean> localOverMap = new HashMap<String, Boolean>();
/**
* 系统初始化的时把商品库存加入到缓存中
* 在容器启动时候,检测到了MiaoshaController类实现了接口InitializingBean之后执行该方法
*/
@Override
public void afterPropertiesSet() throws Exception {
//查询库存数量
List<Map<String, Object>> stockList = miaoshaService.queryAllGoodStock();
System.out.println("系统初始化:"+stockList);
if(stockList == null){
return;
}
for(Map<String, Object> m : stockList) {
//如果不是null的时候,将库存加载到redis里面去 prefix---GoodsKey:spsl, key---商品id,value---商品数量
redisService.set(GoodsKey.getMiaoshaGoodsStock, ""+m.get("goods_id"), m.get("stock_count"));
//添加内存标记
localOverMap.put(m.get("goods_id").toString(), false);
}
}
/**
* QPS:327
* 请求秒杀,redis+Lua方式
*/
@RequestMapping(value="/{path}/do_miaoshalua")
@ResponseBody
public Result<Integer> do_miaoshalua(HttpServletRequest request,HttpServletResponse response){
String userid = "1";//用户id
String goodsId = "1";//库存id
Jedis jedis = jedisPool.getResource();
//脚本里的KEYS参数
List<String> keys = new ArrayList<>();
keys.add(GoodsKey.getMiaoshaGoodsStock.getPrefix()+goodsId);//redis中的商品key
keys.add(OrderKey.getMiaoshaOrderByUidGid.getPrefix()+userid+"_"+goodsId);//redis中的订单key
//脚本里的ARGV参数
List<String> args = new ArrayList<>();
args.add("1");//扣减库存数量
args.add(userid+"_"+goodsId);//用户下单信息
long result = (long) jedis.eval(RedisLua.STOCK_LUA, keys, args);
if(result == -1){
System.out.println("库存不足");
return Result.error(CodeMsg.MIAO_SHA_OVER);
}else if(result == -2){
System.out.println("重复下单");
return Result.error(CodeMsg.REPEATE_MIAOSHA);
}
System.out.println("抢购成功");
//减库存,下订单
Map<String,Object> map = new HashMap<>();
map.put("user_id", userid);
map.put("goods_id", goodsId);
miaoshaService.miaosha(map);
return Result.success(0);
}
/**
* QPS:324
* 请求秒杀,redis watch事务方式
*/
@RequestMapping(value="/{path}/do_miaoshawatch")
@ResponseBody
public Result<Integer> do_miaoshawatch(HttpServletRequest request,HttpServletResponse response){
String userid = "1";//用户id
String goodsId = "1";//库存id
Jedis jedis = jedisPool.getResource();
//监视key
jedis.watch(GoodsKey.getMiaoshaGoodsStock.getPrefix()+goodsId,OrderKey.getMiaoshaOrderByUidGid.getPrefix()+userid+"_"+goodsId);
//库存和订单判断
int count = redisService.get(GoodsKey.getMiaoshaGoodsStock, goodsId,Integer.class);
if(count <= 0){
System.out.println("库存不足");
return Result.error(CodeMsg.MIAO_SHA_OVER);
}
String order = redisService.get(OrderKey.getMiaoshaOrderByUidGid, ""+userid+"_"+goodsId,String.class);
if(order != null && !order.equals("")){
System.out.println("重复下单");
return Result.error(CodeMsg.REPEATE_MIAOSHA);
}
Transaction transaction = jedis.multi();// 开启事务
transaction.set(OrderKey.getMiaoshaOrderByUidGid.getPrefix()+userid+"_"+goodsId, userid+"_"+goodsId);
Response<Long> v = transaction.decrBy(GoodsKey.getMiaoshaGoodsStock.getPrefix()+goodsId,1);
List<Object> result = transaction.exec();
if(result == null || result.isEmpty()){
System.out.println("抢购失败");
}else{
System.out.println("抢购成功,[" + GoodsKey.getMiaoshaGoodsStock.getPrefix()+goodsId + "]剩余:" + v.get().intValue());
//减库存,下订单
Map<String,Object> map = new HashMap<>();
map.put("user_id", userid);
map.put("goods_id", goodsId);
miaoshaService.miaosha(map);
}
return Result.success(0);
}
/**
* QPS:319
* 请求秒杀,redis分布式锁
*/
@RequestMapping(value="/{path}/do_miaoshalock")
@ResponseBody
public Result<Integer> do_miaoshalock(HttpServletRequest request,HttpServletResponse response){
String userid = "1";
String goodsId = "1";
Map<String,Object> orderMap = redisService.get(OrderKey.getMiaoshaOrderByUidGid, ""+userid+"_"+goodsId,Map.class);
if(orderMap != null){
System.out.println("重复下单");
return Result.error(CodeMsg.REPEATE_MIAOSHA);
}
int count = redisService.get(GoodsKey.getMiaoshaGoodsStock, goodsId,Integer.class);
if(count <= 0){
System.out.println("库存不足");
return Result.error(CodeMsg.MIAO_SHA_OVER);
}
Jedis jedis = jedisPool.getResource();
String requestId = UUID.randomUUID().toString();
boolean isOk = RedisLock.tryGetDistributedLock(jedis,GoodsKey.getMiaoshaGoodsStock+goodsId,requestId,10000);
if(isOk){
try{
redisService.decr(GoodsKey.getMiaoshaGoodsStock,goodsId);
Map<String, Object> map = new HashMap<>();
map.put("user_id", userid);
map.put("goods_id", goodsId);
miaoshaService.miaosha(map);
System.out.println("抢购成功");
}finally{
RedisLock.releaseDistributedLock(jedis,GoodsKey.getMiaoshaGoodsStock+goodsId,requestId);//释放锁
}
}else{
System.out.println("该线程未拿到锁");
}
return Result.success(0);
}
/**
* QPS:327
* 请求秒杀,redis+Lua方式(小并发适用)
*/
@RequestMapping(value="/{path}/do_miaosha1")
@ResponseBody
public Result<Integer> do_miaosha1(HttpServletRequest request,HttpServletResponse response,@RequestParam("goodsId")String goodsId,@PathVariable("path") String path){
MiaoshaUser user = userService.getUser(re
没有合适的资源?快使用搜索试试~ 我知道了~
springboot+redis+rebbitmq实现商品秒杀.zip

共193个文件
class:41个
java:41个
js:22个

需积分: 50 28 下载量 55 浏览量
2020-01-07
15:32:47
上传
评论 3
收藏 27.61MB ZIP 举报
温馨提示
springboot+redis+rebbitmq实现商品秒杀demo,通过redid缓存减少数据库访问,rebbitmq消息队列异步下单,极大提高了系统的吞吐量,其中也包含redis分布式锁、redis+watch事务、redis+lua等方式实现的适用于小并发量的秒杀解决方案
资源推荐
资源详情
资源评论
收起资源包目录





































































































共 193 条
- 1
- 2
资源评论


王绍桦
- 粉丝: 136
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 基于Python实现的高性能轻量分布式RPC框架
- 基于Python实现的站内搜索引擎系统设计.zip
- 基于Python实现的动态视频桌面壁纸引擎系统.zip
- 基于Python实现的智能五子棋对战游戏源码.zip
- 基于Python实现的Webshell安全检测工具.zip
- 基于Python实现数据分析自动化报告系统教程.zip
- 基于Python与ADB实现亚马逊自动任务工具.zip
- 基于Python协同过滤的豆瓣电影个性化推荐系统.zip
- 通达信API文档,动态链接库dll,C++源码,C#源码,JAVA源码
- STM32-F103-Rxxx的Keil-MDK的标准外设库模板工程(FreeRTOS)
- 基于Python与Django的在线讲座管理系统.zip
- 基于Python与Django框架的个人博客系统源码.zip
- 基于Python与OpenCV的围棋棋子智能检测系统.zip
- 基于Python与SQLServer的学生商品信息管理系统.zip
- 基于Python与PyQt5的OpenCV图像处理工具系统.zip
- 基于Python与PyTorch的智能车牌检测识别系统.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
