java使用redis实现秒杀

文章目录

  • 前言
  • 一、准备库存数据
  • 二、业务类
  • 三、jmeter测试
    • 1.线程组
    • 2.http请求
    • 3.同步定时器
    • 4.结果树
    • 5.汇总报告
    • 6.查看库存和秒杀成功集合
  • 总结


前言

简单实现redis秒杀场景案例。
java连接redis参考


一、准备库存数据

set 20221101:iphone:stock 500

二、业务类

代码如下(示例):

package com.student.controller;

import com.student.sys.util.JedisPoolUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * Create by zjg on 2022/10/31
 */
@Controller
@RequestMapping("seckill")
public class IPhoneSeckillController {
    private static int count=0;
    /**
     * 双11秒杀苹果
     * @return
     */
    @PostMapping("iphone")
    @ResponseBody
    public Map service(){
        //1.获取jedis连接
        Jedis jedis = null;
        Transaction transaction=null;
        try {
            jedis= JedisPoolUtils.getResource();
            //2.数据准备
            String now = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String stockKey=now+":iphone:stock";
            String stockSet=now+":iphone:set";
            String userID = String.valueOf(new Random().nextInt(1000));
            //3.尝试连接redis
            if(!("PONG".equals(jedis.ping()))){
                return setResponse(1001,"连接redis失败");
            }
            //4.判断库存
            synchronized (this){
                System.out.println(++count+":"+Thread.currentThread().getName()+"用户"+userID+"开始秒杀");
                String stock = jedis.get(stockKey);
                if(stock==null){
                    return setResponse(1002,"库存不足,请明天再来!");
                }
                int currStock = Integer.parseInt(stock);
                if(currStock<=0){
                    return setResponse(1002,"库存不足,请明天再来!");
                }
                //4.1判断用户是否已经存在秒杀成功名单中
                boolean exist = jedis.sismember(stockSet, userID);
                if(exist){
                    return setResponse(1003,"您今天已经秒杀成功,请改天再来!");
                }
                //4.2开启事务
                transaction= jedis.multi();
                transaction.decr(stockKey);
                transaction.sadd(stockSet, userID);
                List<Object> exec = transaction.exec();
                System.out.println(String.format("用户%s秒杀成功",userID));
                System.out.println("当前库存量剩余:"+jedis.get(stockKey));
                System.out.println("当前秒杀成功的用户:"+jedis.smembers(stockSet));
                System.out.println();
            }
        }catch (Exception e){
            if(transaction!=null){
                transaction.discard();
            }
            e.printStackTrace();
            return setResponse(1004,"程序发生未知异常,请稍后重试!");
        }finally {
            //.关闭jedis连接
            jedis.close();
        }
        return setResponse(1000,"秒杀成功");
    }
    public Map setResponse(int code,String msg){
        Map<String,Object> map=new HashMap<>();
        map.put("code",code);
        map.put("msg",msg);
        return map;
    }
}


三、jmeter测试

1.线程组

java使用redis实现秒杀_第1张图片

2.http请求

java使用redis实现秒杀_第2张图片

3.同步定时器

java使用redis实现秒杀_第3张图片

4.结果树

java使用redis实现秒杀_第4张图片

5.汇总报告

java使用redis实现秒杀_第5张图片

6.查看库存和秒杀成功集合

get 20221101:iphone:stock

java使用redis实现秒杀_第6张图片

smembers 20221101:iphone:set

java使用redis实现秒杀_第7张图片


总结

该案例仅供参考。

你可能感兴趣的:(java,java,redis)