0--Secgo-Mall项目简介

🚀 高并发秒杀商城后端系统 (Secgo-Mall)

📖 1. 项目简介与目标

项目作者:Chuan81

项目链接:https://github.com/Chuan81/Secgo-Mall

本项目是一个基于 Go 语言构建的高并发秒杀商城后端系统。系统的核心目标是解决秒杀场景下的两大核心痛点:

  1. 瞬时高并发流量: 保证系统在突发大流量下不宕机,依然保持高可用。

  2. 库存超卖问题: 保证商品库存扣减的绝对准确性,坚决杜绝超卖现象。

🛠️ 2. 技术栈选型与分工

系统采用分层架构设计,各组件职责明确:

  • Web 框架: Gin - 提供高性能的 HTTP 路由与中间件支持。

  • ORM 框架: GORM - 简化 MySQL 数据库操作与事务管理。

  • 关系型数据库: MySQL - 作为核心数据的最终持久化存储,保障数据最终一致性。

  • 缓存与原子操作: Redis - 负责接口限流、活动与库存预热,并利用 Lua 脚本保证扣减库存的原子性。

  • 消息队列: RabbitMQ - 用于异步处理订单创建,实现削峰填谷,保护下游数据库。

  • 配置管理: Viper - 支持动态读取与管理 yaml 配置文件。

  • 无状态鉴权: JWT (JSON Web Token) - 降低服务器存储 Session 的压力,实现快速鉴权。

🏗️ 3. 系统架构与核心流程

3.1 系统分层架构

flowchart LR     %% 接入层     subgraph Entry["接入层"]         client["用户 / App / Web"]         nginx["Nginx 负载均衡"]         client --> nginx     end     %% 应用层     subgraph App["应用层"]         gin["Gin 集群"]         api["API Handler"]         service["Seckill Service"]         jwt["JWT 鉴权"]         gin --> api         api --> service         gin -.-> jwt     end     %% 缓存层     subgraph Cache["缓存层"]         redis["Redis 集群"]         lua["Lua 脚本(原子扣减库存)"]         redis -.-> lua     end     %% 消息层     subgraph MQ["消息层"]         rabbitmq["RabbitMQ"]         worker["消费者 Worker"]         rabbitmq --> worker     end     %% 持久层     subgraph DB["持久层"]         gorm["GORM"]         mysql["MySQL 主从"]         gorm --> mysql     end     %% 支撑组件     subgraph Utils["支撑组件"]         viper["Viper 配置"]         logger["Logger 日志"]         repo["Repository"]         response["统一响应"]         service -.-> repo         repo -.-> gorm     end     %% 主流程     nginx --> gin     gin --> redis     gin --> rabbitmq     worker --> gorm     worker --> redis     gin -.-> response
  • 接入层: Nginx 负载均衡

  • 应用层: Gin 集群(限流、鉴权、业务路由)

  • 缓存层: Redis 集群(库存扣减、防刷、分布式锁)

  • 消息层: RabbitMQ(订单异步排队)

  • 持久层: MySQL 主从架构(最终落库)

3.2 核心秒杀时序图

sequenceDiagram     participant User as 用户     participant Gin as Gin 应用层     participant Redis as Redis (预扣库存)     participant MQ as RabbitMQ (排队)     participant Worker as 消费者 (后台)     participant MySQL as MySQL (落库)     User->>Gin: 1. 发起秒杀请求     Gin->>Gin: 2. JWT 鉴权 & 限流拦截     Gin->>Redis: 3. 执行 Lua 脚本(查库存+扣减)     alt 库存不足或已抢购         Redis-->>Gin: 返回失败         Gin-->>User: 提示“秒杀失败/已罄”     else 扣减成功         Redis-->>Gin: 返回成功         Gin->>MQ: 4. 发送【创建订单】消息         Gin-->>User: 5. 提示“排队中,请稍候”     end     MQ->>Worker: 6. 异步消费消息     Worker->>MySQL: 7. 开启事务:扣真实库存 + 创订单     MySQL-->>Worker: 8. 事务提交成功     Worker->>Redis: 9. 更新订单状态为“已完成”     User->>Gin: 10. 轮询查询订单状态     Gin-->>User: 11. 返回“抢购成功”及支付链接

🔐 4. 核心难点与解决方案

4.1 如何防止超卖?

方案:Redis + Lua 脚本。不在数据库层面做并发扣减,而是在活动开始前将库存预热到 Redis。用户请求到达时,使用 Lua 脚本在 Redis 中单线程原子化执行“检查是否已购买 -> 检查库存 -> 扣减库存 -> 加入购买记录”这四个步骤,彻底阻断超卖可能。

4.2 如何应对瞬时高并发请求保护数据库?

方案:RabbitMQ 削峰填谷。应用层只负责在 Redis 中扣减缓存库存,一旦成功,不立即写库,而是将订单信息扔进 RabbitMQ 后立即给用户返回“排队中”。后台消费者按照数据库能承受的速率平滑拉取消息并执行写库操作。

4.3 如何防止恶意刷单?

方案:Gin 中间件 + Redis 限流

  1. 隐藏秒杀接口: 秒杀开始前接口随机动态生成。

  2. 频次限制: 针对单用户 ID 和单 IP,利用 Redis 令牌桶/固定窗口算法,限制每秒访问次数(例如限制 1秒/5次)。

📁 5. 项目目录结构

Plaintext


seckill-mall/

├── cmd/                # 应用程序入口

│   └── main.go         # 启动文件

├── config/             # 配置相关

│   ├── config.yaml     # 配置文件

│   └── viper.go        # Viper 初始化

├── internal/           # 内部业务代码 (不对外暴露)

│   ├── api/            # 控制器/路由处理层 (Gin Handlers)

│   ├── middleware/     # 中间件 (JWT, 限流等)

│   ├── model/          # 数据模型 (Gorm Models)

│   ├── repository/     # 数据访问层 (MySQL 交互)

│   ├── service/        # 核心业务逻辑层 (秒杀逻辑)

│   ├── cache/          # Redis 交互及 Lua 脚本

│   └── mq/             # RabbitMQ 生产者与消费者

├── pkg/                # 公共工具包 (可被其他项目引用)

│   ├── jwtx/           # JWT 生成与解析工具

│   ├── logger/         # 日志组件

│   └── response/       # 统一 API 返回格式

├── scripts/            # 部署/运维脚本 (Docker, SQL)

├── go.mod

└── README.md

  • cmd/:项目的启动入口。主程序 main.go 会放在 cmd/secgo-mall/ 下。

  • internal/:私有业务逻辑代码(Go 编译器会限制外部项目导入此目录下的包,保证业务代码的封装性)。

- model/:数据模型(如数据库表的结构体定义)。

- repository/:数据访问层(封装所有与 MySQL、Redis 等数据库交互的逻辑)。

- service/:核心业务逻辑层(如处理订单生成、库存扣减等逻辑)。

- api/handlers/:HTTP 路由控制器(接收前端请求、参数校验并调用 Service 层处理)。

  • pkg/:可被外部项目安全复用的公共组件包(如加密解密算法、分布式锁工具等)。

  • configs/:存放项目的配置文件及读取配置的代码。

🚀 6. 快速启动

  1. 待补充
posted @ 2026-04-17 17:24  Chuan81  阅读(57)  评论(0)    收藏  举报