概述
2018.10.24 今天研究了下抢购秒杀的功能实现
网上查了一大堆 用redis的最多。
主要是通过redis的 watch multi 事务来控制秒杀数量 不超卖。
这里说下自己的感受:
不超卖的话 那就要一个个的来减库存 这样的话 效率上会有点问题 这里上下代码 基本上是再网上抄的 。
我用的是 springboot jedis
我就直接上代码了
Controller层
package com.bicon.basedemo.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.annotation.Resource;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
@RestController
@RequestMapping("/test")public classtest {//@Resource//RedisOperation redisOps;
@ResourceprivateJedisPool jedisPool;@RequestMapping("/redis")public voidredisTest() {
Jedis jedis=jedisPool.getResource();
final String watchkeys= "watchkeys";
ExecutorService executor= Executors.newFixedThreadPool(20); //20个线程池并发数
jedis.set(watchkeys, "10");//设置起始的抢购数//jedis.del("setsucc", "setfail");
jedis.close();for (int i = 0; i < 101; i++) {//设置101个人来发起抢购 模拟101个人抢购
executor.execute(newMyRunnable(jedisPool));
}
executor.shutdown();
}public static String getRandomString(int length) { //length是随机字符串长度
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random= newRandom();
StringBuffer sb= newStringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}returnsb.toString();
}
}
MyRunnable 代码
package com.bicon.basedemo.controller;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;public classMyRunnable implements Runnable{privateJedisPool jedisPool;
String userinfo;
String watchkeys= "watchkeys";publicMyRunnable(JedisPool jedisPoo){
jedisPool=jedisPoo;
};public voidrun() {
Jedis jedis=jedisPool.getResource();try{
jedis.watch(watchkeys);//watchkeys
String val= jedis.get(watchkeys);int valint =Integer.valueOf(val);if (valint <= 100 && valint>=1) {
Transaction tx= jedis.multi();//开启事务//tx.incr("watchkeys");
tx.incrBy("watchkeys", -1);
List list = tx.exec();//提交事务,如果此时watchkeys被改动了,则返回null
if (list == null ||list.size()==0) {
System.out.println("重新抢购");this.run();return;
}else{for(Object succ : list){
String succuserifo="succ"+succ.toString() +userinfo ;
String succinfo="用户:" + succuserifo + "抢购成功,当前抢购成功人数:"
+ (1-(valint-10));
System.out.println(succinfo);/*抢购成功业务逻辑*/jedis.setnx(succuserifo, succinfo);
}
}
}else{
String failuserifo="kcfail" +userinfo;
String failinfo1="用户:" + failuserifo + "商品被抢购完毕,抢购失败";
System.out.println(failinfo1);
jedis.setnx(failuserifo, failinfo1);return;
}
}catch(Exception e) {
e.printStackTrace();
}finally{
jedis.close();
}
}
}
最后是效果
这段代码问题其实还是有的:就是没有按照顺来来抢购
其实我觉得有种方法。就是将请求 存入 kafka中
然后取kafka中前面的数据 一直取到抢购的数量(用户不重复)
这样不就可以了吗,不需要考虑超卖问题啥的。纯属自己的感想。
后来看了一个用rabbitMQ 做的 抢购
把请求插入rabbitMQ队列。然后 消费端订阅数据 来实现抢购。
2018-11-21 今天在github上看到一个秒杀的项目 还不错 分享给大家
这个里面有两个 分支,第二个分支是支持rabbitmq的。我觉得 做的还不完美。不过很有借鉴意义。
最后
以上就是精明巨人为你收集整理的java抢购_java redis 实现抢购秒杀的全部内容,希望文章能够帮你解决java抢购_java redis 实现抢购秒杀所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复