项目概述 ​
项目名称:DuolaiMall 商城秒杀项目
项目描述:该项目是模仿京东购物网站的电商项目,提供商品浏览、购买、秒杀等服务
基于SpringCloud的微服务架构进行开发,分为前端和后端
前端提供商品的分类、浏览、搜索;用户的登录、购物车、下单、支付;以及商品的秒杀
后端提供品牌类目,商品spu,sku的CRUD管理
技术选型:SpringBoot2.3 + MyBatisPlus3.4.1 + MySQL5.7 + Maven3.5.3
SpringCloud-Hoxton.SR8 + Docker + Nacos1.4.1 + Redis6.2 + RocketMQ 4.4.0+ ElasticSearch7.8.0 + MinIO
Lombok + FastJson + Redisson + MapStruct
开发环境:Win10 + IDEA2023.2 + JDK1.8
项目周期:2024.1.15 - 2024.2.7
架构图 ​
业务架构图 ​

系统架构图 ​

模块介绍 ​
后台: ​
老师实现的:http://124.220.39.95:8888
- 类目、平台属性、品牌、商品SPU(Standard Product Unit) ,SKU(Stock Keeping Unit)的上架下架,增删改查
前台: ​
老师实现的:http://124.220.39.95:8000
微服务的实现
- Nacos注册中心:服务的注册与自动发现
- Ribbon:服务调用的负载均衡
- OpenFeign:面向接口的服务调用
- Nacos配置中心:配置的外部化、集中化与动态化管理
- SpringCloudGateway:API网关,请求的拦截与路由分发
网关服务
- 网关是微服务项目对外的唯一入口,其核心功能是对外接收请求,对内请求路由。
- 接收浏览器请求时做请求校验。该项目中通过自定义过滤器拦截请求,配合Redis基于共享会话实现Single Sign On单点登录。
- 配置动态路由,实现请求分发。
商品服务
- 使用Spring的AOP,通过自定义注解实现热点数据缓存,提高接口的并发能力与访问速度。
- 基于Redisson实现的分布式锁,实现数据库和缓存的更新,并解决缓存击穿问题。
- Redis中的数据设置随机过期时间,预防缓存雪崩。
- 使用布隆过滤器,规避缓存穿透问题。
- 基于Minio对象存储服务器,存储商品图片等非结构化数据,提高效率。
购物车服务
- 实现未登录也能添加购物车。在网关中,针对所有不需要登录的请求,向用户的请求头添加临时用户Id。登录后合并购物车中的数据。
- 基于Redis实现购物车,提高接口访问速度。
订单服务
- 基于RocketMQ的延迟消息,实现订单超时的自动取消功能
支付服务
- 通过使用支付宝支付SDK,接入支付功能。
- 使用支付宝开放平台提供的沙箱环境进行开发与测试,沙箱环境地址。
- 支付完成后实现同步回调与异步回调接口:
- 同步回调:用户支付完成之后,浏览器发起请求,跳转到支付成功页面。
- 异步回调:用户支付完成之后,支付宝服务器发起请求,把支付结果通知给我们的服务,我们的服务收到请求之后,需要做修改订单状态,修改支付状态,扣减库存等操作。异步回调需要支付宝服务器对我们的服务器发起请求,本项目中使用Natapp做内网穿透。同时,网络抖动可能造成支付宝重新进行异步通知,为了避免重复扣减库存进行了幂等校验。
搜索服务
- 通过使用ElasticSearch,通过商品的各种搜索条件,实现高效的全文检索。
- 基于RocketMQ异步消息,对ES和MySQL实现数据增量同步,实现商品的上下架功能。
- 定时任务每天凌晨,对ES和MySQL中的数据做全量同步。
秒杀服务
- 使用Redis与Spring提供的定时任务实现缓存预热,提高商品页面的访问速度与并发能力。
- 基于消息队列实现秒杀请求的排队处理,实现限流削峰。
- 超卖问题:在执行抢购操作时,扣减库存不具备原子性,多线程并发访问这个共享数据可能会一个库存卖出多次。给库存加分布式锁会严重影响秒杀的效率,本项目中使用Redis的队列来存储商品库存,保证库存扣减的原子性。
仓储服务
- 库存管理系统(Warehouse Management System)主要是和订单、支付、物流等服务交互。本项目不需要关心它的实现细节,只需要调用接口即可。
- 用于判断是否有库存,判断是否需要拆单。
一些优化 ​
- index首页显示的分类数据放在内存里,读取速度更快
- 搜索添加拼音分词器,实现拼音搜索,日期排序
- 购物车,我的订单按照添加日期倒序显示 ,对用户更友好
- 使用Redis主从复制,提高可用性和吞吐量
- 所有显示订单id的地方,“我的订单”,“生成订单“的雪花算法生成的outTradeNo显示。提高数据安全性
- 定时任务实现ES和MySQL数据的全量同步
- 使用Quartz取代Spring定时任务
遇到的问题 ​
- 使用Windows开发时,服务之间的端口占用
- 服务无法启动,报错Failed to introspect annotated methods on class .. 原因:项目中引用了同一个依赖的不同版本
- 雪花算法生成的19位数字id传到前端后精度丢失。解决:使用String类型传id,不要使用Long类型
