从零搭建秒杀服务

news2024/11/16 9:43:41

1. 前言

目的:该项目只用于技术交流,不用于过多商业用途。 

适用:可用于简历亮点、毕业答辩等。

2. 项目成果

2.1 秒杀主页

包含5个功能点:

①、Product Name:秒杀商品名称

②、Product Image:秒杀商品图片

③、Price:秒杀价格

④、Seckill starts in:距离秒杀所剩时间

⑤、Seckill Now:秒杀按钮(核心逻辑)

部分不重要参数,没有做UI设计,只为功能而生

 2.2 秒杀架构

①、MySQL主从复制:一主二从

②、Redis缓存、Redis分布式锁

③、MQ异步处理库存、订单

 

3. 核心代码讲解

3.1 缓存预热

@Override
public void afterPropertiesSet() throws Exception {

    // 缓存秒杀商品
    List<SeckillGoods> seckillGoodsList = seckillMapper.queryAllSeckillGoods();
    for(SeckillGoods goods : seckillGoodsList) {
        String goodsId = goods.getId();
        Integer stock = goods.getGoodsStock();
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put(CONSTANT.SECKILLGOODS, goodsId, stock);
    }

    // 缓存秒杀订单
    List<SeckillOrder> seckillOrderList = seckillMapper.queryAllSeckillOrder();
    for(SeckillOrder seckillOrder : seckillOrderList) {
        String userId = seckillOrder.getUserId();
        String goodsId = seckillOrder.getGoodsId();
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put(CONSTANT.SECKILLORDER, userId + "," + goodsId, CONSTANT.SECKILLORDER);
    }

}

3.2 核心业务逻辑

@Override
public Map<String, String> buySeckillGoods(String userId, String goodsId) {

    Map result = new HashMap<String, String>();

    RLock lock = redisson.getLock(CONSTANT.SECKILLLOCK); // 拿不到会自己阻塞

    try {
        lock.lock();
        // 检查Redis秒杀商品是否有库存
        Integer stock = (Integer) redisTemplate.opsForHash().get(CONSTANT.SECKILLGOODS, goodsId);
        if(stock <= 0) {
            result.put("msg", "秒杀商品库存不足!");
            result.put("success", "400");
            return result;
        }

        // 检查该用户是否秒杀过该商品
        Object orderConstant = redisTemplate.opsForHash().get(CONSTANT.SECKILLORDER, userId + "," + goodsId);
        if(orderConstant != null) {
            result.put("msg", "该用户已经秒杀过该商品了!");
            result.put("success", "400");
            return result;
        }

        // Redis新增订单
        String orderId = UUID.randomUUID().toString();
        SeckillOrder seckillOrder = new SeckillOrder();
        seckillOrder.setId(orderId);
        seckillOrder.setGoodsId(goodsId);
        seckillOrder.setUserId(userId);

        redisTemplate.opsForHash().put(CONSTANT.SECKILLORDER, userId + "," + goodsId, CONSTANT.SECKILLORDER);

        // Redis减少库存
        redisTemplate.opsForHash().put(CONSTANT.SECKILLGOODS, goodsId, stock-1);

        // MQ处理库存和订单
        rabbitTemplate.convertAndSend("seckillGoodsExchange", "seckillGoodsRouting", seckillOrder);
        rabbitTemplate.convertAndSend("seckillOrderExchange", "seckillOrderRouting", seckillOrder);

    }catch (Exception e) {
        e.printStackTrace();
    }finally {
        lock.unlock(); // 解锁
    }

    result.put("msg", "秒杀商品成功!");
    result.put("success", "200");
    return result;
}

4. 其他

还存在其他的补充点(订单支付超时、订单真实支付、MQ消息问题、Redis单机问题等),如果喜欢请三连,我会继续更新。

需要完整代码或帮忙搭建环境,请留下邮箱。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/757465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Multiframe-to-Multiframe Network for Video Denoising

Multiframe-to-Multiframe Network for Video Denoising 摘要 现存方法&#xff1a;多相邻帧恢复一个干净帧&#xff0c;效果好但是由于按顺序去噪考虑可能造成视频闪烁&#xff1b; 本文&#xff1a;提出一个多帧对多帧的去噪模型&#xff0c;从连续噪声帧中恢复多个干净帧…

【通览一百个大模型】GLM(THU)

【通览一百个大模型】GLM&#xff08;THU&#xff09; 作者&#xff1a;王嘉宁&#xff0c;本文章内容为原创&#xff0c;仓库链接&#xff1a;https://github.com/wjn1996/LLMs-NLP-Algo 订阅专栏【大模型&NLP&算法】可获得博主多年积累的全部NLP、大模型和算法干货资…

基础算法-【区间合并】

题目 给定 n 个区间 [li,ri]&#xff0c;要求合并所有有交集的区间。 注意如果在端点处相交&#xff0c;也算有交集。 输出合并完成后的区间个数。 例如&#xff1a;[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。 输入格式 第一行包含整数 n。 接下来 n行&#xff0c;每行…

《远见》阅读笔记

不同的环境&#xff0c;不同的职业&#xff0c;职业生涯的建议并没有什么不同 找到热爱的工作&#xff0c;建立热爱的生活 如何思考职业远景 如何分配时间 如何扩张人脉 职业生涯决策框架 三个部分 职场思维、框架、工具实用性建议和案例现实生活为基础&#xff0c;平衡职…

MacOS触控板缩放暂时失灵问题解决

我的系统版本为Monterey 12.5.1&#xff0c;亲测有效 直接创建脚本xxx.sh&#xff0c;并在终端执行脚本bash xxx.sh即可解决此问题&#xff0c;脚本内容如下&#xff1a; #!/bin/bashkillall Finder #kill Finder如不需要可以删除 killall Dock #kill Dock 如不需要可以删…

一文详细介绍什么是数据标注?

机器学习和深度学习算法都依赖于数据&#xff0c;为构建可靠的人工智能模型&#xff0c;需要为算法提供结构良好且标注良好的数据。 为了让机器学习算法学习如何完成特定任务&#xff0c;我们必须标注它们用于训练的数据。换句话说&#xff0c;标注数据很简单&#xff0c;但并不…

pytorch深度学习 之二 拟合数据 从线性到非线性

目的 深入了解线性回归的使用方法&#xff0c;使用非线性激活函数&#xff0c;同时使用pytorch的nn模块&#xff0c;最后使用神经网络来求解线性拟合&#xff0c;只有深入了解了基础&#xff0c;才能做出更高水平的东西。 上一章 神经网络梯度下降和线性回归 拟合定义数据 …

php代码审计15.3之phar伪协议与反序列化

文章目录 1、基础2、生成phar格式文件3、例子4、小试牛刀 1、基础 在漏洞的利用过程之中&#xff0c;我们需要先本地生成phar格式的文件&#xff0c;而生成phar格式的文件&#xff0c;需要将php.ini中的phar.readonly配置项配置为0或Off。目标服务器端是不必开启此配置&#x…

设计模式07-责任链模式

责任链模式属于行为设计模式&#xff0c;常见的过滤器链就是使用责任链模式设计的。 文章目录 1、真实开发场景的问题引入2、责任链模式讲解2.1 核心类及类图2.2 基本代码 3、利用构建者模式解决问题4、责任链模式的应用实例5、总结5.1 解决的问题5.2 使用场景5.3 优缺点 1、真…

计算机的工作原理(操作系统篇)

文章目录 1.操作系统的定位1.硬件2.驱动3.操作系统内核4.系统调用 2.进程3.PCB中有哪些描述进程的特征4.内存管理 1.操作系统的定位 先看一张图: 1.操作系统是最接近硬件的软件,是软件/硬件/用户之间交互的媒介; 2.操作系统起到一个管理的作用 1)对下,要管理硬件设备 2)对上,…

【100天精通python】Day4:运算符

目录 1 算数运算符 2 赋值运算符 3 比较&#xff08;关系运算符&#xff09; 4 逻辑运算符 5 位运算符 6 运算符的优先级 以下是一个完整的示例代码&#xff0c;用于计算学生三科成绩的分差和平均分&#xff1a; 1 算数运算符 Python中的算术运算符包括&#xff1a; 加…

如何在pd里设置win10虚拟机command+w关闭chrome浏览器的一个标签页

背景 在windows&#xff0c;我们知道 ctrlw 在chrome浏览器里可以关闭一个标签页&#xff0c;但是对于MacOS&#xff0c;pd的虚拟机里安装win10后&#xff08;pdparallel desktop)&#xff0c;commandw默认并不是料想中的相当于ctrlw关闭一个标签页&#xff0c;而是关闭所有的…

MPP概述

前言 最近忙于工作&#xff0c;有一段时间没更新自己的博客了&#xff0c;也就意味着囤积了一波需要梳理总结并记录的知识点&#xff0c;但可以保证的是所有都是零星的知识点&#xff0c;不会涉及工作内容。 一、MPP简介 MPP (Massively Parallel Processing)&#xff0c;即大…

Cisco学习笔记(CCNA)——Internetworking

Internetworking Internetworking Basics 什么是网络&#xff1f; 计算机网络&#xff1a;具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来 网络设备 Hub&#xff08;集线器&#xff09; 优点&#xff1a;便宜、操作简单 缺点&#xff1a;共享型、…

Set与Map的使用 + 二叉搜索树与哈希桶的大白话讲解和图解+完整代码实现(详细注释)

文章目录 前言一、Set与Map概念及场景模型纯Key模型Key-Value模型 Map 的使用Set 的使用 二、二叉搜索树什么是二叉搜索树代码实现二叉搜索树查找操作插入操作删除操作(难点)cur这个节点没有左子树(cur.left null)cur这个节点没有右子树(cur.right null)cur这个节点没有左右子…

springboot与rabbitmq的整合【演示5种基本交换机】

前言&#xff1a; &#x1f44f;作者简介&#xff1a;我是笑霸final&#xff0c;一名热爱技术的在校学生。 &#x1f4dd;个人主页&#xff1a;个人主页1 || 笑霸final的主页2 &#x1f4d5;系列专栏&#xff1a;后端专栏 &#x1f4e7;如果文章知识点有错误的地方&#xff0c;…

基于梯度下降的线性回归(Gradient Descent For Linear Regression)

概述&#xff1a; 梯度下降是很常用的算法&#xff0c;它不仅被用在线性回归上和线性回归模型、平方误差代价函数。在本次&#xff0c;我们要将梯度下降和代价函数结合。我们将用到此算法&#xff0c;并将其应用于具体的拟合直线的线性回归算法里。 梯度下降算法和线性回归算法…

Cell 子刊 | 深度睡眠脑电波调节胰岛素敏感性促进血糖调节

缺乏高质量的睡眠会增加一个人患糖尿病的风险。然而&#xff0c;为什么会这样仍然是一个不解之谜。 近期&#xff0c;加州大学伯克利分校的一组睡眠科学家的新发现为我们揭示了答案。研究人员在人体内发现了一种潜在的调控机制&#xff0c;解释了为什么夜间深度睡眠脑电波能够调…

数据结构(王道)——线性表之静态链表顺序表和链表的比较

一、静态链表 定义&#xff1a; 代码实现&#xff1a; 如何定义一个静态链表 静态链表的基本操作思路&#xff1a; 初始化静态链表&#xff1a; 静态链表的查找、插入、删除 静态链表总结&#xff1a; 二、顺序表和链表的比较 逻辑结构对比&#xff1a; 存储结构对比&#xff…

golang关于成员变量使用:=

错误 错误原因 结构体成员变量不能与:一起用&#xff0c;这是一个语法错误。