dubbo系列(四) 凑一下热闹 使用dubbo redis mybatis mysql 实现商品秒杀功能

jmeter实现并发抢购

使用我的pc tomcat使用默认设置, 商品为5000个,未优化测试结果最高qps1400

开了两个dubbo服务

秒杀前准备数据

创建list存到redis里, 如果一个商品有5000件,list的大小为5000

redis数据

这里用到了redis批量插入数据,具体实现看看上面的代码吧, 用到了setnx实现锁功能,使用到redis 数据格式有string,list,map三种

抢购逻辑实现

待优化的内容

  Object value = redisTemplate.opsForList().leftPop(goodQueueCache.getCacheKey());
        if (value != null) {
//这里待优化
}

优化的代码如下

public class SaveMiaoShaOrderRunner implements Runnable {
    private Logger logger = LoggerFactory.getLogger(SaveMiaoShaOrderRunner.class);
    private ConcurrentLinkedQueue<MiaoshaOrder> miaoshaOrdersQueue;
    private MiaoshaService miaoshaService;

    public SaveMiaoShaOrderRunner(ConcurrentLinkedQueue<MiaoshaOrder> miaoshaOrdersQueue, MiaoshaService miaoshaService) {
        this.miaoshaOrdersQueue = miaoshaOrdersQueue;
        this.miaoshaService = miaoshaService;
    }

    @Override
    public void run() {
        logger.info("开始保存订单...");
        List<MiaoshaOrder> miaoshaOrders = new ArrayList<>();
        int  size = 0;
        MiaoshaOrder order;

        for (int i = 0; i < 1000; i++) {
            //获取并移除此队列的头,如果此队列为空,则返回 null。
            order = miaoshaOrdersQueue.poll();
            if (order == null) {
                break;
            } else {
                miaoshaOrders.add(order);
                size++;
            }
        }
        if (size > 0) {
            miaoshaService.batchSave(miaoshaOrders);
            miaoshaOrders.clear();
        }

    }
}
MiaoshaServiceImpl增加以下代码
   @PostConstruct
    public void initSaveDbThread() {
        MyExecutors.SINGLE_SCHEDULED_EXECUTOR_SERVICE.scheduleWithFixedDelay(//
                new SaveMiaoShaOrderRunner(miaoshaOrdersQueue, this),2, 2, TimeUnit.SECONDS);
    }

优化后使用我的pc tomcat使用默认设置, 商品为40,000个,测试结果qps最高到1700

看一下数据库,没有超卖

库存数没有更新,这个是没有实现了,不是bug哦, 可以新开一个线程每几秒统计一下redis list的大小,然后更新到数据库中

原文地址:https://www.cnblogs.com/LDDXFS/p/9946586.html