
@SpringBootTest(classes = xxx.class)
@ComponentScan(basePackages = "com.xx.xx.xx")
public class SecKill {
@Resource
private RedissonClient redissonClient;
String delayQueue = "secKill-delay-queue";
@Test
public void kill() {
ExecutorService executorService = new ThreadPoolExecutor(500, 1000, 500, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10), new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 1; i < 20000; i++) {
int userId = i;
executorService.execute(() -> {
tryKill(userId);
});
}
try {
TimeUnit.SECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Test
public void tryKill(Integer userId) {
RBlockingQueue<String> killBlockingQueue = redissonClient.getBlockingQueue("secKill-queue");
int queueSize = killBlockingQueue.size();
AssertUtils.isTrue(queueSize < 600, "商品已售罄" + userId);
killBlockingQueue.offer(userId.toString());
}
@Test
public void genToken() {
RBlockingQueue<String> secKillQueue = redissonClient.getBlockingQueue("secKill-queue");
try {
while (true) {
String userId = secKillQueue.take();
RAtomicLong rAtomicLong = redissonClient.getAtomicLong("kill-stock");
boolean exists = rAtomicLong.isExists();
if (!exists) {
System.out.println("活动已经结束");
continue;
}
if (rAtomicLong.get() < 1) {
System.out.println("库存不足");
continue;
}
long count = rAtomicLong.getAndDecrement();
if (count < 1) {
System.out.println("库存不足");
continue;
}
String token = UUID.randomUUID().toString().replace("-", "");
String promoId = "1";
String promo_token = "promo_token:promo_token_" + promoId + "_user_id_" + userId;
redissonClient.getBucket(promo_token).set(token, 2, TimeUnit.MINUTES);
RBlockingQueue<String> killBlockingQueue = redissonClient.getBlockingQueue(delayQueue);
RDelayedQueue<String> killDelayedQueue = redissonClient.getDelayedQueue(killBlockingQueue);
killDelayedQueue.offer(promo_token, new Random().nextInt(100), TimeUnit.SECONDS);
System.out.println(String.format(" %s userId = %s , token= %s", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), userId, token));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Test
public void checkKillQualification() {
String promoId = "1";
String userId = "";
String promo_token = "promo_token_" + promoId + "user_id_" + userId;
RBucket<String> rBucket = redissonClient.getBucket(promo_token);
String token = rBucket.get();
AssertUtils.isTrue(StringUtils.hasText(token), "抢购商品失败");
}
@Test
public void secSettlement(Integer userId) {
token String userToken = "kk";
String promoId = "1";
String promo_token = "promo_token:promo_token_" + promoId + "user_id_" + userId;
RBucket<String> rBucket = redissonClient.getBucket(promo_token);
String serviceToken = rBucket.get();
AssertUtils.isTrue(userToken.equals(serviceToken), "秒杀令牌已过期");
cart_item Map<String, String> cartItem = new HashMap<>(); cartItem.put("promo_id", "1");
cartItem.put("user_id_", "1001");
cartItem.put("amount", "0.01");
cartItem.put("pay_status", "1");
}
@Test
public void submitOrder(Integer userId) {
Map<String, String> cartItem = new HashMap<>();
Map<String, String> order = new HashMap<>();
order.put("promo_id", cartItem.get("promo_id"));
order.put("user_id_", cartItem.get("user_id_"));
order.put("total_amount", cartItem.get("amount"));
order.put("pay_amount", "0.01");
Token String promoId = "1";
String promo_token = "promo_token_" + promoId + "user_id_" + userId;
redissonClient.getBucket(promo_token).delete();
}
@Test
public void rollbackStock() {
RBlockingQueue<String> rBlockingQueue = redissonClient.getBlockingQueue(delayQueue);
redissonClient.getDelayedQueue(rBlockingQueue);
while (true){
try {
String token = rBlockingQueue.take();
long count = redissonClient.getAtomicLong("kill-stock").incrementAndGet();
System.out.println(String.format("恢复库存 = %s",count));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}