一句话定位:2018 年那篇「从 0 到 1 构建分布式秒杀系统」的配套代码,把单机锁、数据库悲观锁与乐观锁、Redis 与 ZooKeeper 分布式锁、JVM 队列、Disruptor、Redis 订阅、Kafka 这些秒杀方案各写了一遍,放在同一个工程里对照着跑。它是教学案例,作者自己在 README 里写明「某些案例并不适用于生产环境」;仓库还在,但代码停在上一个时代(Spring Boot 1.5.10 + Swagger 2)。
项值
仓库地址https://gitee.com/52itstyle/spring-boot-seckill
项目定位分布式秒杀系统的教学 Demo,一份代码演示多种并发控制方案
作者 / 站点小柒2012(52itstyle),博客 https://blog.52itstyle.vip
开源协议Apache-2.0(LICENSE 全文,Copyright 2018 小柒2012)
后端技术栈Spring Boot 1.5.10 / Java 8 / Spring Data JPA / MySQL / Thymeleaf
中间件Redis、ZooKeeper(Curator)、Kafka、ActiveMQ,Disruptor、Redisson
前端形态Thymeleaf + NekoHTML + FreeMarker 静态化,页面用 iView / jQuery
服务入口8080 端口,contextPath /seckill,Swagger 在 /seckill/swagger-ui.html
仓库状态374 次提交,4 个分支(master、20200818、20180810、20180528),0 个标签
社区热度Gitee 14.5K Star / 6K Fork / 2.2K Watch / 24 Open Issues / 5 PR(2026-11-10 查询)
荣誉Gitee GVP 项目
文档日期2026-11-10

1. 项目是什么

它是一份「秒杀系统怎么做」的代码合集,不是一套能直接上线的秒杀平台。 同一个工程里放了好几条并行的实现路径:先用单机锁顶住,再换数据库锁,再换 Redis 分布式锁,再换 ZooKeeper,最后用消息队列把请求削峰。每种方案都能单独跑起来,访问对应的 Controller 就能对比效果。

理解这个仓库,先理解它的叙事结构:

层次对应代码解决的问题
业务模型Seckill、SuccessKilled 两张表商品库存、秒杀成功记录(唯一索引防重复)
单机并发lock/LockDemo、aop/LockAspectsynchronized、ReentrantLock、AOP 切面锁
数据库并发悲观锁 for update、乐观锁版本号不引中间件时的最朴素方案
分布式锁distributedlock/redis、distributedlock/zookeeper多机部署时锁必须跨进程
异步削峰queue/jvm、queue/disruptor、queue/redis、queue/kafka把「下单」从同步链路里摘出去
页面优化CreateHtmlServiceImpl + FreeMarker商品详情静态化,挡住读请求
入口防护验证码、Guava 限流、Sentinel防刷、限流

需要先认清三点:

  • 它是 2018 年的文章配套代码。README 里的架构讨论(高防 IP、SLB、Nginx 限流、DRDS 读写分离)是「应该怎么做」的讲解,仓库里的实现只是其中可演示的一小块。
  • 每种方案都是独立 Demo,不是一套可切换的架构。代码里没有「策略模式选一种锁」这种设计,而是各写一个 Service 实现,你按需调用。
  • 作者已经明确它不面向生产。README 原话:「本测试案例单纯为了学习,某些案例并不适用于生产环境」,「项目正在完善中(仅供参考)」。

2. 核心特性

特性说明学习价值
一张表讲清秒杀模型seckill 存库存与时间窗,success_killed 用联合主键防重复秒杀的核心约束是「一人一单 + 库存不超卖」
三种单机锁对照synchronized、ReentrantLock、AOP 注解锁直观看到锁粒度与吞吐的差别
数据库悲观锁select ... for update 锁行理解行锁与事务边界
数据库乐观锁版本号 CAS 更新,影响行数为 0 即失败无锁方案的典型写法
Redisson 分布式锁封装好的可重入锁,带看门狗续期生产里最常用的方案之一
ZooKeeper 分布式锁Curator InterProcessMutex理解临时顺序节点与公平锁
JVM 进程内队列LinkedBlockingQueue + 线程池消费单机削峰的最小实现
Disruptor 队列RingBuffer 无锁队列高吞吐场景的经典组件
Redis 订阅队列pub/sub 做异步通知轻量消息通道
Kafka 队列生产/消费分离真正的跨机削峰
页面静态化FreeMarker 生成商品详情 HTML读多写少场景的第一层优化
接口文档Swagger 2.7 在线调试直接点页面就能复现并发效果
限流组件Guava RateLimiter、Sentinel演示「限流先于加锁」

3. 技术架构

整体结构:单体 Spring Boot 应用,内嵌 Tomcat,页面用 Thymeleaf 渲染,数据走 JPA,缓存与锁走 Redis,异步走队列,静态化走 FreeMarker。没有注册中心、没有网关,一切都在一个 jar 里。

层技术说明
框架Spring Boot 1.5.10.RELEASE2018 年初的版本,spring-boot-starter-parent 直接锁死
Web内嵌 Tomcatserver.tomcat.max-threads=100,contextPath /seckill
持久层Spring Data JPA + MySQLmysql-connector-java 未锁版本,走 Boot 的依赖管理
模板Thymeleaf + NekoHTMLLEGACYHTML5 模式,允许不闭合标签
静态化FreeMarkerspring.freemarker.html.path 指定输出目录
缓存 / 会话spring-boot-starter-redis 1.4.7 + spring-session会话存 Redis,多机共享
分布式锁Redisson 2.11.5 / Curator 2.10.0Redis 与 ZooKeeper 两条路
消息spring-kafka 1.3.5、ActiveMQ、beanstalkc三种队列都留了示例
高吞吐队列Disruptor 3.4.1RingBuffer 实现
限流Guava 25.1、Sentinel 1.6.3一个本地、一个可配规则
文档springfox-swagger2 2.7.0老版 Swagger,路径 /swagger-ui.html
监控spring-boot-starter-actuator管理端口单独开在 28806
工具Lombok、fastjson 1.2.83、commons-lang3常规工具集

代码分层(com.itstyle.seckill):

包职责
web三个入口:SeckillController(单机)、SeckillDistributedController(分布式)、CreateHtmlController(静态化)
service / service.impl每种方案一个实现,SeckillServiceImpl、SeckillDistributedServiceImpl、CreateHtmlServiceImpl
repositoryJPA 仓储,SeckillRepository
entitySeckill、SuccessKilled、Result
enumsSeckillStatEnum,秒杀状态与提示语
common.lock / common.aop锁示例与 @Servicelock 注解切面
distributedlock.redisRedisson 配置、工具类与 Demo
distributedlock.zookeeperCurator 分布式锁工具
queue.jvm进程内队列 + TaskRunner 消费线程
queue.disruptor事件、工厂、生产者、消费者
queue.redis发布/订阅与消息监听容器
queue.kafka生产者与消费者
common.dynamicquery原生 SQL 动态查询封装
common.redisRedis 配置与工具类
common.apiSwagger 配置
common.interceptor拦截器适配器

几个关键取舍:

  • 用 JPA 而不是 MyBatis:Demo 里 SQL 简单,JPA 少写映射;代价是复杂查询要靠 dynamicquery 那套原生 SQL 封装兜底。
  • 一个工程塞多种方案:对照学习很方便,但依赖也因此变重——Kafka、ZooKeeper、ActiveMQ、Beanstalkd、腾讯云 SDK 全在 pom 里,实际跑某个 Demo 用不到这么多。
  • 队列用四种实现:进程内、Disruptor、Redis、Kafka 各写一遍,是「教学」而不是「选型」,生产里只需要一种。
  • 前端停留在 Thymeleaf + iView:2018 年的写法,今天看已经过时,但它不是这个项目的重点。

4. 目录结构

路径用途
src/main/java/com/itstyle/seckill/Application.java启动类
src/main/java/.../web/控制器:单机秒杀、分布式秒杀、静态页生成
src/main/java/.../service/业务接口与各方案实现
src/main/java/.../distributedlock/Redis(Redisson)与 ZooKeeper(Curator)分布式锁
src/main/java/.../queue/四套队列:jvm、disruptor、redis、kafka
src/main/java/.../common/aop/切面锁 LockAspect 与注解 Servicelock
src/main/java/.../common/lock/单机锁演示
src/main/java/.../common/entity/实体:Seckill、SuccessKilled、Result
src/main/resources/application.properties主配置:数据源、Redis、Kafka、ZooKeeper、验证码、Actuator
src/main/resources/sql/建表与初始化数据脚本
src/main/resources/templates/Thymeleaf 页面:商品列表、详情、结果页(1000–1003)
src/main/resources/static/前端资源:jQuery、iView、商品图、详情页样式
src/main/resources/template/goods.fltFreeMarker 静态化模板
src/main/resources/redis/Windows 版 Redis 压缩包,方便本地跑
pom.xml依赖清单,Spring Boot 1.5.10
数据库/、服务器/、架构之路/作者整理的文档与配图,不是可运行代码
Java Basis/Java 基础示例,与秒杀主流程无关
README.md项目说明、架构讲解、参考文章列表

仓库里混进了大量非代码内容(HTML 与图片占了语言统计的三分之一),clone 下来会比预期大。redis/ 目录直接放了 Windows 版 Redis 压缩包,这在开源仓库里不常见,也解释了为什么它能在 Windows 上「开箱跑」。

5. 快速上手

前置条件

JDK 8、Maven、MySQL 5.7/8.0、Redis。要跑分布式 Demo,还得有 ZooKeeper 3.4.6 与 Kafka。作者建议在 Linux 下装这些中间件。

第一步:建库导数据

mysql -uroot -p
# 登录后依次执行
CREATE DATABASE seckill DEFAULT CHARSET utf8mb4;
USE seckill;
source src/main/resources/sql/seckill.sql

如果脚本路径或文件名与仓库当前版本不一致,以 src/main/resources/sql 下的实际文件为准。

第二步:改配置

application.properties 里至少要改这几处:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/seckill?characterEncoding=utf-8
spring.datasource.username=你的账号
spring.datasource.password=你的密码
spring.redis.host=127.0.0.1
spring.redis.port=6379
zookeeper.address=127.0.0.1:2181
spring.kafka.bootstrap-servers=127.0.0.1:9092

只跑单机 Demo 的话,ZooKeeper 与 Kafka 的地址可以不管,但相关 Bean 在启动时可能仍会尝试连接,遇到报错就把对应 Controller 与队列类先注释掉。

第三步:启动

mvn clean package -DskipTests
java -jar target/spring-boot-seckill-0.0.1-SNAPSHOT.jar

或者在 IDEA 里直接跑 Application 的 main 方法。

第四步:验证

  • 接口调试:http://localhost:8080/seckill/swagger-ui.html
  • 秒杀商品页:http://localhost:8080/seckill/index.shtml(README 注明部分功能待完成)
  • 管理端口:http://localhost:28806,Actuator 端点开在这里

用工具压一下

页面点按钮只能验证逻辑,要看并发效果得用压测工具。作者文章里用的是 JMeter 一类工具,对同一个秒杀地址并发请求,观察 success_killed 表的行数是否等于库存。这一步才是这个项目真正的价值所在——看不同方案在同样的并发下,超卖与吞吐差多少。

6. 功能模块清单

模块能做什么对应代码
秒杀列表展示进行中与即将开始的商品templates/index.html
商品详情库存、时间、秒杀按钮templates/1000.html 等
单机秒杀synchronized 或 ReentrantLock 扣库存SeckillServiceImpl
AOP 切面锁注解式加锁,业务代码无侵入LockAspect + @Servicelock
数据库悲观锁for update 锁行SeckillServiceImpl 悲观锁方法
数据库乐观锁版本号 CAS 更新SeckillServiceImpl 乐观锁方法
Redis 分布式锁Redisson 加锁、解锁RedissLockUtil
ZooKeeper 分布式锁Curator 互斥锁ZkLockUtil
进程内队列请求入队,后台线程扣库存SeckillQueue + TaskRunner
Disruptor 队列RingBuffer 事件流转SeckillEventProducer / Consumer
Redis 队列发布订阅异步处理RedisSender / RedisConsumer
Kafka 队列跨机削峰KafkaSender / KafkaConsumer
静态化生成商品详情静态 HTMLCreateHtmlServiceImpl
验证码腾讯云验证码防刷配置项 qq.captcha.*
限流Guava RateLimiter、Sentinelcommon 下示例
通知WebSocket 推送秒杀结果spring-boot-starter-websocket

7. 版本与授权

项实际情况
版本号没有版本号。pom.xml 里是 0.0.1-SNAPSHOT,仓库 0 个 Git 标签
分支4 个:master、20200818、20180810、20180528,按日期命名
许可证Apache-2.0,LICENSE 全文,版权行写「Copyright 2018 小柒2012」
维护状态README 自述「项目正在完善中(仅供参考)」;代码主体停留在 2018–2020 年
荣誉Gitee GVP

Apache-2.0 对使用者的意义:

  • 可以商用、闭源修改、对外分发,只需保留版权与许可声明,修改过的文件加注说明;
  • 带专利授权条款;
  • 作者不提供任何担保,「按现状」提供。

但要注意:协议的宽松不代表代码可以直接上生产。这份代码的价值在于演示并发控制思路,业务完整性(支付回调、超时未支付释放库存、退款、风控)并不在其中。

8. 商业模式说明

这个仓库本身不卖钱,Apache-2.0 免费。它的作用有两个:

  1. 技术内容引流。作者博客(52itstyle.vip)围绕这个项目写了一整个系列:分布式锁、限流、Disruptor、静态化、验证码、重复下单、WebSocket 通知,每篇都对应仓库里的一段代码。这套内容为作者积累了 GVP 与 14.5K Star。
  2. 给商业产品导流。现在打开 README,最上面一整屏是多商户商城源码的销售广告(小柒商城:S2B2C、B2B2C、B2C、O2O 多模式,含装修、分账、直播、拼团等),往下翻很久才看到原来的秒杀内容。仓库简介也被改成了「Java 商城框架,商城开发事半功倍」。

也就是说,这个仓库现在的第一身份是商业商城源码的展示位,第二身份才是秒杀教学案例。判断它是否还值得参考时,看代码提交而不是看 README 首屏。

变现路径也很典型:个人 IP(博客、公众号、QQ 群)+ 源码授权 + 二开定制。这在国产 Java 开源圈里是最常见的一种模式。

9. 生态与周边

项目 / 资源作用地址
作者博客秒杀系列文章,逐篇对应代码blog.52itstyle.vip
SPTools作者的极简开发工具箱gitee.com/52itstyle/SPTools
spring-boot-pay支付服务示例gitee.com/52itstyle/spring-boot-pay
spring-boot-quartz任务调度示例gitee.com/52itstyle/spring-boot-quartz
spring-boot-sharding-sphere分库分表、读写分离案例gitee.com/52itstyle/spring-boot-sharding-sphere
spring-boot-elasticsearch搜索服务示例gitee.com/52itstyle/spring-boot-elasticsearch
抢红包案例高并发抢红包、延迟队列作者博客 archives 系列
交流群QQ 群 933593697—
API 文档Gitee ApiDoc 页apidoc.gitee.com/52itstyle/spring-boot-seckill

生态上要说清楚:没有官方镜像站、没有 Docker 镜像、没有 Helm,也没有配套的前端工程。它是一个「代码 + 文章」的组合,周边全靠作者博客串联。

10. 选型建议

适合你,如果:

  • 你想系统搞懂秒杀里各种锁与队列的差别,需要能跑的对照代码;
  • 你在准备面试或做技术分享,需要一套能把「超卖」「重复下单」「削峰」讲清楚的示例;
  • 你要给团队做并发编程培训,希望有现成的 Demo 改;
  • 你在评估某个方案(比如 Redisson 与 Curator 哪个更顺手),想先跑个最小验证。

不适合你,如果:

  • 你要一套能上线的秒杀/抢购系统——业务完整性远远不够;
  • 你的项目已经是 Spring Boot 2.x/3.x,这份 1.5.10 的代码没法直接搬,只能抄思路;
  • 你不想装 Kafka、ZooKeeper 这一堆中间件;
  • 你需要有人维护、有版本、有 changelog 的依赖。

和同类怎么比:市面上讲秒杀的仓库大多只有一种实现(多半是 Redis + Lua 扣库存)。这个项目的优势是横向铺得全,能在一套代码里横向对比;劣势是纵向都不深,每个方案都是 Demo 级,缺生产细节(幂等、补偿、对账、降级)。把它当教材,不要当脚手架。

11. 风险与坑

  • 它明确不是生产系统:README 自己写「某些案例并不适用于生产环境」「仅供参考」。拿它上线,支付、退款、库存回滚、风控全都要自己补。
  • 配置文件里是明文的默认口令:spring.datasource.username=root、password=root,Redis 密码注释掉默认空。改配置是第一件要做的事。
  • 内网 IP 写死在配置里:Kafka 的 bootstrap-servers 与 ZooKeeper 的 address 默认指向 192.168.1.180,这个地址是作者当时的实验环境,直接启动会一直重连。
  • Actuator 的关机端点开着:endpoints.shutdown.enabled=true、management.security.enabled=false、管理端口 28806 独立暴露。这意味着任何能访问 28806 的人都能把服务关掉。这是 Spring Boot 1.5 时代最典型的安全坑,务必关掉 shutdown 端点并加访问控制。
  • JPA 的 ddl-auto=update:启动时按实体自动改表结构,本地方便,生产上随时可能改坏索引或字段。生产必须改成 none 并用 SQL 迁移。
  • 静态页输出路径写死 Windows 盘符:spring.freemarker.html.path = D://file//,Linux 上要改成实际目录,否则静态化功能直接报错。
  • Spring Boot 1.5.10 早已结束维护:Spring Framework 4.3 分支的已知漏洞不会再修,内嵌 Tomcat 版本也很老。要用于任何对外服务,先把框架升级评估做掉——但升级基本等于重写,1.5 到 2.x 的配置项、Actuator、安全模型都变了。
  • 依赖版本互相打架:spring-boot-starter-redis 锁在 1.4.7(Boot 1.5 时代已被 spring-boot-starter-data-redis 取代)、spring-kafka 1.3.5、Curator 2.10 对应 ZooKeeper 3.4.6。这些版本必须成套使用,单独升一个大概率启动失败。
  • 0 个标签、分支按日期命名:想追某个时间点的代码只能按分支名猜,没有 changelog,也没有 release 包。
  • README 首屏已是商业广告:判断项目状态请看提交记录与代码,别被首屏的商城宣传误导成「这是个商城系统」。
  • 仓库体积偏大:架构之路/、数据库/、服务器/ 三个目录塞了大量图片与文档,static/ 里还有商品图,clone 会比预期慢。
  • 验证码依赖腾讯云:qq.captcha.* 四个参数是作者账号的掩码值,要自己申请腾讯云验证码服务并换掉,否则防刷环节跑不通。
  • Demo 只覆盖「抢到」这一步:下单成功后的支付、超时关单、库存回补、通知,README 的「思考改进」里自己列成了待办。做业务时这些才是主要工作量。
  • 压测结论不能外推:本机 Redis/单机 MySQL 下的 QPS 数字没有参考意义,换环境就变。要评估得在自己的目标环境压。

12. 参考链接

名称地址
代码仓库(Gitee)https://gitee.com/52itstyle/spring-boot-seckill
作者博客https://blog.52itstyle.vip
项目 Wiki / 文档https://gitee.com/52itstyle/spring-boot-seckill/wikis
Swagger 调试入口(本地)http://localhost:8080/seckill/swagger-ui.html
秒杀商品页(本地)http://localhost:8080/seckill/index.shtml
Apache-2.0 协议全文https://www.apache.org/licenses/LICENSE-2.0
分库分表示例https://gitee.com/52itstyle/spring-boot-sharding-sphere
支付服务示例https://gitee.com/52itstyle/spring-boot-pay
开发工具箱 SPToolshttps://gitee.com/52itstyle/SPTools

本文基于 2026-11-10 的 master 分支源码(pom.xml、application.properties、README、目录结构)、Gitee 项目页与作者博客整理;Star 数、分支与标签数量均以该日为准。项目为教学案例,代码与文章存在时间差,落地前请以仓库实际内容为准。

标签: Java, 秒杀, 高并发

添加新评论