1 Star 0 Fork 22

wurong/goodsKill

forked from techa/goodsKill 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

前言

License Java CI with Maven codecov CodeQL

项目命名为 goodsKill 一方面有商品秒杀的意思(好像有点chinglish的味道),另外也可理解为 good skill,本项目就是希望搭建一套完整的项目框架,把一些好的技术和开发技巧整合进来(偏向于后端技术),方便学习和查阅。

本项目为模拟秒杀项目,提供统一秒杀模拟请求接口,方便自行测试各个秒杀方案的执行速度。 技术上整体采用SpringMVC + Mybatis持久层框架,采用Dubbo3.x[1],服务注册发现以及配置中心使用Nacos,支持数据库分库分表、分布式事务,使用状态机完成数据状态间的转换(基于Spring Statemachine实现)。

💎 分支介绍

master分支基于最新Spring Cloud 2022.x+ Spring Boot 3.x + JDK17体系构建,目前仅保留核心的模拟秒杀API接口,如需使用Spring Boot 2.7.x + JDK11版本可以切换到tag v2.7.4(支持登录注册以及简单的后台管理功能)。master分支目前升级改造中,功能不够稳定,如遇代码报错建议使用老版本。

本项目功能目前比较简陋且有很多不完善的地方,真实的秒杀场景远比本项目中的实现方式复杂,本项目省略了真实场景中的部分技术实现细节,目前仅作学习参考之用,如果觉得本项目对你有帮助的请多多star支持一下👍~~。

附:码云项目链接 https://gitee.com/techa/goodsKill,clone速度慢的用码云仓库拉吧,不定期同步到码云~

✨ 技术选型

使用的工具或框架 名称 官网

Spring Boot

Spring Boot框架

https://spring.io/projects/spring-boot

MyBatis-Plus

MyBatis增强工具

https://mp.baomidou.com/

ZooKeeper

分布式协调服务

http://zookeeper.apache.org/

Redis

分布式缓存数据库

https://redis.io/

Kafka

消息队列

http://kafka.apache.org/

RabbitMQ

消息队列

https://www.rabbitmq.com/

MongoDB

Mongo数据库

https://www.mongodb.com/

MySQL

MySQL数据库

https://www.mysql.com/

Elasticsearch

全文搜索引擎

https://www.elastic.co

Sharding-JDBC

分库分表组件

https://shardingsphere.apache.org

Spring Cloud Alibaba

Cloud Alibaba组件

https://github.com/alibaba/spring-cloud-alibaba

Apache Dubbo

RPC服务远程调用框架

https://github.com/apache/dubbo

Spring Cloud Gateway

网关组件

https://spring.io/projects/spring-cloud-gateway

Kotlin

Kotlin

https://kotlinlang.org/

Seata

分布式事务解决方案

http://seata.io/zh-cn/index.html

Spring Security OAuth2.0

OAuth2.0授权组件

https://spring.io/projects/spring-security-oauth

Canal

基于MySQL数据库的增量日志解析工具

https://github.com/alibaba/canal

GraphQL

一种用于 API 的查询语言

https://docs.spring.io/spring-graphql/docs/current/reference/html

Spring Statemachine

Spring 状态机

https://spring.io/projects/spring-statemachine

📝 项目模块介绍

goodsKill
|--goodskill-admin                          ||SpringBoot Admin监控服务端,支持Spring Cloud微服务发现
|--goodskill-canal                          ||用于完成MySQL数据库binlog收集的canal客户端程序
|--goodskill-gateway                        ||微服务网关,支持动态路由加载
|--goodskill-order-provider                 ||订单服务提供者
|   |--goodskill-order-service
|--goodskill-seckill-provider               ||秒杀服务提供者
|   |--goodskill-api                        ||提供服务API接口
|   |--goodskill-service                    ||服务API接口实现
|--goodskill-spring-boot-starter            ||项目配置自动装配
|--goodskill-web                            ||提供秒杀模拟接口访问
|--goodskill-job                            ||elastic-job定时任务
|--goodskill-seata                          ||集成nacos+dubbo+shardingjdbc+seata的分布式事务解决方案示例
|--goodskill-auth                           ||auth登录以及授权模块
|   |--auth-service                         ||基于本项目用户体系的用户登录授权服务
    |--oauth2-auth-server                   ||oauth2.0登录授权服务端,自定义的登录授权服务
    |--oauth2-resource-server               ||oauth2.0资源服务端,自定义的登录授权服务

🔥🔥 秒杀方案

目前实现了几种秒杀方案,通过SeckillMockController提供测试接口

聚合网关Openapi文档地址: http://localhost/doc.html#/home(需要开启网关服务)

Spring Boot Admin应用监控地址: http://www.goodskill.com:19031, 登录用户名密码:user/123456

  • 场景一:Sychronized同步锁实现

  • 场景二:Redisson分布式锁实现

  • 场景三:ActiveMQ实现(已废弃)

  • 场景四:Kafka消息队列实现

  • 场景五:数据库原子性更新

  • 场景六:实时等待秒杀处理结果(已废弃)

  • 场景七:ZooKeeper分布式锁

  • 场景八:使用Redis进行秒杀商品减库存操作,秒杀结束后异步发送MQ,使用MongoDB完成数据落地

  • 场景九:Spring Cloud Stream实现

  • 场景十:Sentinel限流+数据库原子性更新(需搭配sentinel控制台配置资源名limit的流控规则)

  • 场景十一:数据库原子性更新 + Canal数据库binlog日志监听秒杀结果

可在web控台查看秒杀结果,打印信息类似:
2021-04-14 21:58:59.857  INFO [goodskill-web,df43cc8f59291c48,df43cc8f59291c48] 15808 --- [           main] o.s.w.controller.SeckillMockController   : 秒杀场景二(redis分布式锁实现)开始时间:Wed Apr 14 21:58:59 CST 2021,秒杀id:1000
2021-04-14 21:59:00.094  INFO [goodskill-web,144aa7910cca9520,2821cb8d62c5a908] 15808 --- [AClOSzbugzYng-1] o.s.w.s.c.SeckillMockResponseListener    : 秒杀活动结束,秒杀场景二(redis分布式锁实现)时间:Wed Apr 14 21:59:00 CST 2021,秒杀id:1000
2021-04-14 21:59:00.101  INFO [goodskill-web,144aa7910cca9520,2821cb8d62c5a908] 15808 --- [AClOSzbugzYng-1] o.s.w.s.c.SeckillMockResponseListener    : 最终成功交易笔数统计中。。。
2021-04-14 21:59:01.616  INFO [goodskill-web,144aa7910cca9520,2821cb8d62c5a908] 15808 --- [AClOSzbugzYng-1] o.s.w.s.c.SeckillMockResponseListener    : 最终成功交易笔数统计中。。。
2021-04-14 21:59:03.129  INFO [goodskill-web,144aa7910cca9520,2821cb8d62c5a908] 15808 --- [AClOSzbugzYng-1] o.s.w.s.c.SeckillMockResponseListener    : 最终成功交易笔数:10
2021-04-14 21:59:03.130  INFO [goodskill-web,144aa7910cca9520,2821cb8d62c5a908] 15808 --- [AClOSzbugzYng-1] o.s.w.s.c.SeckillMockResponseListener    : 历史任务耗时统计:StopWatch '': running time = 36159894800 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
4492195700  012%  秒杀场景四(kafka消息队列实现)
3164155900  009%  秒杀场景八(秒杀商品存放redis减库存,异步发送秒杀成功MQ,mongoDb数据落地)
6219218300  017%  秒杀场景十(Sentinel限流+数据库原子性更新)
9189080600  025%  秒杀场景七(zookeeper分布式锁)
3135926500  009%  秒杀场景五(数据库原子性更新update set num = num -1)
3342791800  009%  秒杀场景九(基于springcloud stream rabbitmq)
3343433700  009%  秒杀场景一(sychronized同步锁实现)
3273092300  009%  秒杀场景二(redis分布式锁实现)

🧰 开发环境版本说明

  • JDK: OpenJDK17

  • Sharding-JDBC: 5.3.2

  • SpringCloud: 2022.x.x

  • SpringBoot: 3.x.x

  • SpringCloudAlibaba: 2022.x.x

  • Apache Dubbo: 3.x

  • Kotlin: 1.7.x

  • 使用的Docker镜像

    镜像 版本 端口 用户名密码

    Nacos

    2.2.3

    8848

    nacos:nacos

    Redis

    latest

    6379

    密码:123456

    Kafka

    3.1.1

    9092

    KafkaManager

    latest

    9001:9000

    Mongo

    6.0.7

    27017

    MySQL

    8.0.29

    3306

    root:Password123

    Zookeeper

    3.6.2

    2181

    Elasticsearch

    7.17.3

    9200 9300

    Kibana

    7.17.3

    5601

    RabbitMQ

    latest

    5672 15672

🎯 快速开始

  • 项目根目录goodsKill中执行

      mvn clean install
      或
      #跳过单元测试
      mvn clean install -DskipTests
  • 默认端口启动nacos、redis、mysql、rabbitmq、kafka、zookeeper、elasticsearch,或者使用docker-compose[2]命令:

      docker-compose -f goodskill-simple.yml up -d
  • 进入goodskill-web/src/main/sql目录,找到seckill.sql文件,在本地mysql数据库中建立seckill仓库并执行完成数据初始化操作

    ⚠️️
    docker-compose启动MySQL镜像时会自动执行初始化脚本,如已执行过上一步本步骤可跳过
  • 配置host

     127.0.0.1       kafka
     127.0.0.1       nacos
     127.0.0.1       redis
     127.0.0.1       mysql
     127.0.0.1       zookeeper
     127.0.0.1       mongo
     127.0.0.1       elasticsearch
     127.0.0.1       rabbitmq
     127.0.0.1       logstash
     ##如果网关服务部署在远程机器,此处改为相应的远程机器ip
     127.0.0.1       www.goodskill.com
  • main方法运行OrderApplication类(订单服务)

  • main方法运行SeckillApplication类(秒杀管理服务提供者)

  • main方法运行SampleWebApplication类(模拟秒杀web服务)

  • 启动完成后发送一个秒杀模拟请求: 秒杀活动id 1000,商品数量10,执行20次购买操作,使用sychronized同步锁执行,例如:

    Example 1. 使用sychronized同步锁执行
    curl -X POST "http://www.goodskill.com:8080/sychronized" \
    -H "accept: */*" -H "Content-Type: application/json" -d \
    "{ \"requestCount\": 20, \"seckillCount\": 10, \"seckillId\": 1000}"
    Example 2. 使用Redisson分布式锁执行
    curl -X POST "http://www.goodskill.com:8080/redisson" \
    -H "accept: */*" -H "Content-Type: application/json" -d \
    "{ \"requestCount\": 20, \"seckillCount\": 10, \"seckillId\": 1000}"
    Example 3. 使用Redisson分布式锁执行,支持动态配置后台线程池核心线程数以及最大线程数
    curl --location --request POST 'http://www.goodskill.com:8080/limit' \
    --header 'User-Agent: apifox/1.0.0 (https://www.apifox.cn)' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "maxPoolSize": 10,
        "seckillId": 1000,
        "corePoolSize": 2,
        "seckillCount": 100,
        "requestCount": 120
    }'

    请求默认异步执行,可在控制台查看执行日志,如果最终成功交易笔数等于商品数量10则表示没有出现超卖或者少卖问题

🕹️️ 启动完整项目步骤

在快速开始部分基础上增加以下步骤即可启动一个完整项目

  • 进入goodskill-gateway模块,通过GatewayApplication类main方法启动服务网关

  • 找到AuthApplication类main方法启动远程服务

额外功能(可选)

  • 已集成Sentinel限流组件,支持nacos配置中心方式推送限流规则,使用时需启动Sentinel控制台,并以18088端口启动,docker环境暂不支持。

  • Seata分布式事务测试方法见 Seata分布式事务测试示例运行说明

  • main方法运行GoodskillAdminApplication类(微服务健康状态指标监控)

❓常见问题

  1. docker es镜像启动失败

    出现此问题一般为linux环境,运行以下命令即可 sysctl -w vm.max_map_count=262144 ,或者修改/etc/sysctl.conf文件,追加以下配置:

    grep vm.max_map_count /etc/sysctl.conf
    vm.max_map_count=262144
  2. 如何使用本项目自定义的OAuth2.0授权服务器进行登录授权?

    待完善。。

  3. 项目集成的各个框架之间目前的兼容性如何,可以参考本项目的配置在生产环境使用吗?

    本项目目前依赖的各个主流框架的版本比较新,尚未经过完整测试,目前仅用于学习。如果要在生产环境使用,建议使用官方推荐的稳定版本。比如目前的Spring Cloud Alibaba Dubbo官方不建议生产上使用,Spring Cloud Alibaba官方推荐的稳定版为2.2.x[3]

  4. 服务启动控制台报ERROR日志 no available service found in cluster 'default', please make sure registry config correct and keep your seata server running 如何解决?

    启动seata-server服务即可(docker-compose.yml文件中已提供),可参照Seata官网添加nacos相关配置。如未使用分布式事务,可忽略该错误,不影响服务正常运行

  5. docker-compose无法拉取镜像

    hub.docker被墙,国内可使用阿里云镜像加速器,具体操作见 阿里云镜像加速器

  6. 使用JDK17启动项目失败

    启动时添加以下jvm参数,例如:

    --add-opens java.base/java.lang=ALL-UNNAMED
    --add-opens java.base/java.util=ALL-UNNAMED
    --add-opens java.base/java.util.concurrent=ALL-UNNAMED
    --add-opens java.base/java.math=ALL-UNNAMED
    --add-opens java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED

🖲️ 状态机说明

目前秒杀活动状态的控制基于Spring Statemachine状态机实现,使用状态机的优点:

  • 统一控制活动状态,便于状态的集中维护;

  • 防止业务状态被随意更改,保证状态的可控更新;

状态机流程图

image

📚分库分表情况说明

数据库 是否分库 分库字段 是否分表 分表字段

success_killed

MySQL

是(同一服务器中,分为seckill和seckill_01两个库)

seckill_id

是(分为success_killed_0,success_kill_1两张表)

user_phone

📢
其他表均未分库分表,默认使用seckill作为主库

🔖服务网关说明

API接口说明

image

💻相关页面展示

模拟秒杀接口测试

image

📑数据库表结构

image

📖参考文档


1. 由于SpringCloudAlibaba官方暂未支持Dubbo 3.x,本项目采用dubbo-spring-boot-starter集成
MIT License Copyright (c) 2024 techa03 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

基于慕课网秒杀项目扩展了部分功能,完善登录注册以及用户角色权限管理,使用dubbo搭建分布式服务调用,模块化设计,集成了gradle和maven两种构建工具,最新分支基于springboot2.x构建 展开 收起
Java
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/zy5201314/goodsKill.git
git@gitee.com:zy5201314/goodsKill.git
zy5201314
goodsKill
goodsKill
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385