spring boot + Mybatis + redis 秒杀系统
2017-09-19 09:18
501 查看
最近开了一些高并发的东西,以及一些秒杀系统,但感觉都没有完整的描述。于是自己就动手实现了一个简单版本的抢购系统。
本系统采用spring boot + mybatis + redis实现。
项目结构图如下:
项目工程已放到GitHub上了,https://github.com/feibabm/seckill,需要的请自行下载。
本文主要借鉴网上一些通用的做法,做出一个例子,主要实现了一个抢购接口:
http://localhost:8080/seckill/product/1?userId=1
seckill.sql文件为建表sql
pro_insert.sql文件为success_killed表中数据添加10000条用户预约记录
seckill_insert.sql文件为seckill生成一条产品信息
具体验证逻辑是执行test文件夹下的两个test类:
RemoteInvote.java
RemoteInvote2.java
这两个test类没有什么差别,主要是为了增加并发量
主要的抢票逻辑如下:
自己用两进程线程,大概两分钟掉了20000次,暂时没有出现啥问题。如果有什么问题,希望大家指出,谢谢。
本系统采用spring boot + mybatis + redis实现。
项目结构图如下:
项目工程已放到GitHub上了,https://github.com/feibabm/seckill,需要的请自行下载。
本文主要借鉴网上一些通用的做法,做出一个例子,主要实现了一个抢购接口:
http://localhost:8080/seckill/product/1?userId=1
seckill.sql文件为建表sql
pro_insert.sql文件为success_killed表中数据添加10000条用户预约记录
seckill_insert.sql文件为seckill生成一条产品信息
具体验证逻辑是执行test文件夹下的两个test类:
RemoteInvote.java
RemoteInvote2.java
这两个test类没有什么差别,主要是为了增加并发量
主要的抢票逻辑如下:
public SecKillResult secKillProduct(String userPhone, long productId) { String state = (String)redisTemplate.opsForValue().get(userPhone + "_"+ productId); //用户信息加载 if(null == state){ SuccessKilled successKilled = new SuccessKilled(); successKilled.setSeckillId(productId); successKilled.setUserPhone(Long.valueOf(userPhone)); successKilled = successKilledMapper.selectOne(successKilled); if(null == successKilled){ return new SecKillResult(false, "该用户没有预约"); }else{ synchronized (this){ state = (String)redisTemplate.opsForValue().get(userPhone + "_"+ productId); if(null == state){ redisTemplate.opsForValue().set(userPhone + "_" + productId, successKilled.getState().toString(), 300, TimeUnit.SECONDS); state = String.valueOf(successKilled.getState()); } } } } if(state.equals("-1")){ //查询产品信息 // ProductInfo productInfo = (ProductInfo)redisTemplate.opsForValue().get(productId + ""); List values = redisTemplate.opsForHash().values(productId + ""); if(values.size() == 0){ Seckill seckill = seckillMapper.selectByPrimaryKey(productId); if(null == seckill){ return new SecKillResult(false, "没有该秒杀商品信息"); } synchronized (this){ if(!redisTemplate.opsForHash().hasKey(productId + "", "number")){ // productInfo = new ProductInfo(seckill.getSeckillId(), seckill.getNumber(), seckill.getStartTime(), seckill.getEndTime()); HashMap<String, String> productHash = new HashMap<>(); productHash.put("number", seckill.getNumber() + ""); productHash.put("startTime", seckill.getStartTime().getTime() + ""); productHash.put("endTime", seckill.getEndTime().getTime() + ""); redisTemplate.opsForHash().putAll(productId +"", productHash); redisTemplate.expire(productId + "", 300, TimeUnit.SECONDS); values = redisTemplate.opsForHash().values(productId + ""); } } } if( new Date(Long.valueOf((String)values.get(1))).after(new Date(System.currentTimeMillis()))){ return new SecKillResult(false, "抢购还没有开始"); } else if(new Date(Long.valueOf((String)values.get(2))).before(new Date(System.currentTimeMillis()))){ return new SecKillResult(false, "抢购已经结束"); } else { Long userState = redisTemplate.opsForValue().increment(userPhone + "_" + productId, 1); if(userState == 0){ // Long increment = redisTemplate.opsForValue().increment(productId, -1); Long number = redisTemplate.opsForHash().increment(productId + "", "number", -1); if(number >= 0){ //消息队列异步更新库存,以及用户的预约信息 QueueEntity queueEntity = new QueueEntity(userPhone, productId); ExecutorPool.queue.offer(queueEntity); }else { return new SecKillResult(false, "商品已经抢购完成"); } }else { redisTemplate.opsForValue().increment(userPhone + "_" + productId, -1); return new SecKillResult(false, "您已抢购过该产品"); } } } else { return new SecKillResult(false, "您已抢购过该产品"); } return null; }
自己用两进程线程,大概两分钟掉了20000次,暂时没有出现啥问题。如果有什么问题,希望大家指出,谢谢。
相关文章推荐
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- 基于SpringMVC+Spring+MyBatis实现秒杀系统【概况】
- 基于Spring+SpringMVC+Mybatis的秒杀系统之Dao层(1)
- 基于Spring+SpringMVC+Mybatis的秒杀系统之web层(3)
- SpringBoot之Mybatis操作中使用Redis做缓存
- mybatis二级缓存springboot-redis
- Spring Cloud Spring Boot mybatis分布式微服务云架构(三十五)使用Redis做集中式缓存(1)
- spring boot 整合mybatis,redis,热部署
- Spring Cloud Spring Boot mybatis分布式微服务云架构(二十一)使用Redis数据库(1)
- Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦
- Spring Boot + Mybatis + Ehcache 精准系统架构基本配置
- springboot 整合 redis 主从同步 sentinel哨兵 实现商品抢购秒杀
- 基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(十七)【权限架构系统(基础框架搭建)】
- SSM实战——秒杀系统之DAO层实体定义、接口设计、mybatis映射文件编写、整合Spring与Mybatis
- Springboot + Mybatis+Dubbo+Zookeeper+nginx+redis+HTML
- spring boot+mvc+mybatis+netty-sokey.io+html+js实现简单即时通讯聊天系统