本项目是基于Spring Boot与Redis深度整合的前后端分离的点评平台。系统以Redis为核心技术支撑,重点解决高并发场景下的缓存穿透、击穿、雪崩等问题,涵盖商户展示、优惠券秒杀、达人探店、社交互动等创新功能。
用户服务:
商户服务:
秒杀服务:
社交服务:
链接:
链接1
链接2
链接3
本项目是基于Spring Boot的校园生活服务系统,分为管理端(供校内商家使用)和用户端(微信小程序)。管理端包括员工信息、商品及分类的管理,订单状态跟踪等功能;用户端在线浏览商品,添加购物车及下单等功能。
管理端
1、用户登录(JWT、ThreadLocal)
2、员工信息维护
3、商品管理
4、分类管理
5、订单状态跟踪
6、来单/催单提醒(webSocket实时推送)
7、Spring Cache缓存菜品信息
8、定时任务处理超时订单(Spring Task)
用户端(微信小程序)
1、微信登陆
2、商品浏览(Redis缓存)
3、购物车管理
4、下单支付
序号 | 模块 | 作用 |
---|---|---|
1 | sky-take-out | maven父工程,统一管理依赖版本,聚合其他子模块 |
2 | sky-common | 子模块,存放公共类,例如:工具类、常量类、异常类等 |
3 | sky-pojo | 子模块,存放实体类、VO、DTO等 |
4 | sky-server | 子模块,后端服务,存放配置文件、Controller、Service、Mapper等 |
使用JWT令牌和自定义拦截器完成用户认证的流程如下:
每个线程都有⼀个ThreadLocalMap的内部属性,map的key是ThreaLocal,定义为弱引用,value是强引用类型。垃圾回收的时候会⾃动回收key,但对应的 Value 仍然是强引用,且线程未结束时,ThreadLocalMap 会一直持有该 Value,导致内存泄漏。
解决⽅法:每次使⽤完ThreadLocal就调⽤它的remove()⽅法,手动将对应的键值对删除,从⽽避免内存泄漏
它由三部分组成:header(头部)、payload(载荷)、signature(签名)
缓存商品 用户端小程序展示的商品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大。结果是系统响应慢、用户体验差。通过Redis来缓存商品数据,减少数据库查询操作。缓存逻辑是每个分类的商品下缓存一份数据,数据库中商品数据有变更时及时清理数据。key是分类的id,value是该分类下所有商品信息
在项目中,我们采用分布式锁策略实现数据库与Redis的数据同步。通过Redis分布式锁(如Redisson)对数据ID细粒度加锁,确保同一时间只有一个请求能修改数据;在锁内严格按"先更新数据库→再删除缓存"的顺序操作,保证后续请求必然读取最新数据;
因为有库存价格等信息所以不适合用延时双删)。
修改频率较低所以加锁性能损耗不高
Nginx 的负载均衡功能允许将请求分发给多个应用服务器,以均衡负载和提高系统的可扩展性和可靠性。下面是一些常用的 Nginx 负载均衡配置方法:
upstream webservers{
server 127.0.0.1:8080 weight=90 ;
#server 127.0.0.1:8088 weight=10 ;
}
反向代理隐藏服务器,正向代理隐藏客户端。
反向代理优点:
提高访问速度,因为nginx本身可以进行缓存,如果访问的同一接口,并且做了数据缓存,nginx就直接可把数据返回,不需要真正地访问服务端,从而提高访问速度。
进行负载均衡,把大量的请求按照我们指定的方式均衡的分配给集群中的每台服务器。
保证后端服务安全因为一般后台服务地址不会暴露,所以使用浏览器不能直接访问,可以把nginx作为请求访问的入口,请求到达nginx后转发到具体的服务中,从而保证后端服务的安全。
反向代理配置。在nginx.conf配置
server {
listen 80;
server_name localhost;
# 反向代理,处理管理端发送的请求
location /api/ {
proxy_pass http://localhost:8080/admin/;
#proxy_pass http://webservers/admin/;
}
# 反向代理,处理用户端发送的请求
location /user/ {
proxy_pass http://webservers/user/;
}
}
WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。
特性 | WebSocket | HTTP |
---|---|---|
连接性质 | 全双工(双向实时通信) | 半双工(单向请求-响应) |
持久性 | 长连接(建立后持续保持) | 短连接(默认每次请求后关闭) |
主动推送 | 服务端可主动推送数据 | 服务端只能被动响应客户端请求 |
这两个功能对实时性要求极高,传统的HTTP请求-响应模式无法满足毫秒级推送的需求,因此我们采用WebSocket协议实现服务端主动推送,确保商家能第一时间处理订单。
我们使用WebSocket实现了两个核心功能: ✅ 来单实时提醒:当用户下单并支付成功后,系统立即通知商家端有新订单。 ✅ 客户催单处理:用户点击催单按钮后,商家端实时收到催单通知,并触发语音播报。
通过WebSocket实现管理端页面和服务端保持长连接状态。当客户支付完成或者点击催单后,调用WebSocket的相关API实现服务端向客户端推送消息,客户端浏览器解析服务端推送的消息,判断是来单提醒还是客户催单,进行相应的消息提醒和语言播报
Spring Task(Spring 任务调度)是 Spring 框架提供的一种任务调度框架,用于执行定时任务、异步任务、任务监听、任务调度等。
苍穹外卖采用Spring Task实现订单超时自动取消功能,核心逻辑是每分钟扫描一次数据库中订单,筛选出创建时间超过15分钟且状态为"待支付"的订单,批量修改为"已取消"状态
序号 | 表名 |
---|---|
1 | employee(员工表) |
2 | category(分类表) |
3 | dish(菜品表) |
4 | dish_flavor(菜品口味表) |
5 | setmeal(套餐表) |
6 | setmeal_dish(套餐菜品关系表) |
7 | user(用户表) |
8 | address_book(地址表) |
9 | shopping_cart(购物车表) |
10 | orders(订单表) |
11 | order_detail(订单明细表) |
完成微信支付有两个关键的步骤:
1️⃣ 就是需要在商户系统当中调用微信后台的一个下单接口,就是生成预支付交易单。
2️⃣ 就是支付成功之后微信后台会给推送消息。
如果都按照之前的操作方式来处理这些公共字段(创建时间,创建人id,修改时间,修改人id), 需要在每一个业务方法中进行操作, 编码相对冗余、繁琐。我们使用AOP切面编程,实现功能增强,来完成公共字段自动填充功能。
实现步骤:
1). 自定义注解 AutoFill,用于标识需要进行公共字段自动填充的方法
2). 自定义切面类 AutoFillAspect,统一拦截加入了 AutoFill 注解的方法,通过反射为公共字段赋值
3). 在 Mapper 的方法上加入 AutoFill 注解
链接:
1、链接1
2、链接2
3、链接3
4、链接4
5、链接5