企业级商城秒杀(redis+java等后端技术)

_

下面给你一份:

企业级 秒杀系统(Redis + Java)

核心目标:

高并发
防超卖
防重复下单
高性能

这是:

企业中经典面试 + 实战项目


一、秒杀核心问题

秒杀最怕:


1、超卖

库存:

100

结果卖:

1000

2、重复下单

一个人疯狂抢。


3、数据库崩溃

10万人同时:

update stock = stock -1

数据库直接炸。


二、企业真实方案

真正企业:

Redis + Lua脚本

保证:

原子性

三、秒杀流程(企业核心)

用户请求
    ↓
Redis判断库存
    ↓
Redis判断是否重复下单
    ↓
扣减库存
    ↓
记录用户
    ↓
发送MQ异步创建订单

四、为什么 Redis 适合秒杀

因为:

Redis:

单线程 + 内存

极快。


五、项目结构

controller
service
redis
mq
order

六、依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.27.2</version>
</dependency>

七、Redis配置

spring:
  data:
    redis:
      host: localhost
      port: 6379

八、秒杀 Controller

@RestController
@RequestMapping("/seckill")
@RequiredArgsConstructor
public class SeckillController {

    private final SeckillService seckillService;

    @PostMapping("/{voucherId}")
    public String seckill(
            @PathVariable Long voucherId
    ) {

        Long userId = 1L;

        return seckillService.seckill(voucherId, userId);
    }
}

九、秒杀核心 Service(重点)

这是:

企业核心代码


@Service
@RequiredArgsConstructor
public class SeckillService {

    private final StringRedisTemplate redisTemplate;

    /**
     * 秒杀
     */
    public String seckill(
            Long voucherId,
            Long userId
    ) {

        // 库存key
        String stockKey =
                "seckill:stock:" + voucherId;

        // 用户key
        String orderKey =
                "seckill:order:" + voucherId;

        // Lua脚本
        String script = """

                -- 1.判断库存
                local stock =
                tonumber(redis.call('get', KEYS[1]))

                if stock <= 0 then
                    return 1
                end

                -- 2.判断是否重复下单
                if redis.call(
                    'sismember',
                    KEYS[2],
                    ARGV[1]
                ) == 1 then
                    return 2
                end

                -- 3.扣减库存
                redis.call(
                    'decr',
                    KEYS[1]
                )

                -- 4.保存用户
                redis.call(
                    'sadd',
                    KEYS[2],
                    ARGV[1]
                )

                return 0
                """;

        // 执行 Lua
        Long result = redisTemplate.execute(
                new DefaultRedisScript<>(
                        script,
                        Long.class
                ),
                List.of(stockKey, orderKey),
                userId.toString()
        );

        // 结果判断
        if (result == 1) {

            return "库存不足";
        }

        if (result == 2) {

            return "不能重复下单";
        }

        // =========================
        // 企业里这里会:
        // 发MQ创建订单
        // =========================

        return "秒杀成功";
    }
}

十、为什么企业用 Lua

因为:

Redis Lua脚本:

是原子执行。


十一、如果不用 Lua

例如:

if(stock > 0){

   stock--;

}

高并发下:

一定超卖


十二、Lua 原子性(核心)

Lua脚本:

执行期间
不会被其他线程打断

所以:


判断库存


判断重复


扣库存


保存用户


全部原子完成


十三、Redis 数据结构设计(企业重点)


库存

seckill:stock:1

value:

100

已下单用户

seckill:order:1

使用:

Set

存:

1
2
3

十四、为什么用 Set

因为:

天然去重

非常适合:

一人一单


十五、企业真实架构(重点)

真正企业:

不会:

直接写数据库

而是:


Redis负责抗高并发


MQ异步下单

例如:

Redis秒杀成功
    ↓
发送MQ
    ↓
订单系统消费
    ↓
写数据库

十六、为什么必须 MQ

因为:

数据库:

扛不住秒杀流量


十七、企业真实秒杀架构

Nginx
   ↓
Gateway
   ↓
Redis Lua秒杀
   ↓
Kafka/RabbitMQ
   ↓
订单服务
   ↓
MySQL

十八、企业优化(非常重要)

真正企业:

还会:


1、本地缓存


2、Redis集群


3、限流

例如:

令牌桶

4、黑名单


5、防刷


6、验证码


十九、为什么秒杀是经典项目

因为:

它包含:

  • Redis

  • Lua

  • MQ

  • 高并发

  • 分布式

  • 缓存

  • 限流

几乎:

后端核心技术全覆盖


二十、真正企业面试重点

面试官真正问:


为什么用 Lua


为什么不会超卖


Redis 为什么单线程还能快


为什么要 MQ


如何保证订单一致性


如何防止重复下单


如何抗10万QPS

这些才是:

企业核心。

Object::isNull踩坑 2026-04-23
Dubbo 自定义异常 + fastjson2 序列化踩坑记录 2026-05-12

评论区