Java项目拷打(外卖+点评)

news2025/7/11 10:09:32

一、点评星球(黑马点评)

1、项目概述

1.1、项目简介

本项目是基于Spring Boot与Redis深度整合的前后端分离的点评平台。系统以Redis为核心技术支撑,重点解决高并发场景下的缓存穿透、击穿、雪崩等问题,涵盖商户展示、优惠券秒杀、达人探店、社交互动等创新功能。

1.2、项目亮点

  • 使用 Redis 解决了在集群模式下的 Session共享问题,使用双拦截器实现用户的登录校验和权限刷新
  • 运用Cache Aside模式解决数据库与缓存的一致性问题,通过主动更新结合超时删除保证最终一致性
  • 使用 Redis 对高频访问的信息进行缓存,降低数据库查询压力,解决了缓存穿透、雪崩、击穿问题
  • 使用 Redis + Lua脚本实现对用户秒杀资格的预检,同时用乐观锁解决秒杀产生的超卖问题
  • 使用 Redisson分布式锁解决在集群模式下一人一单的线程安全问题
  • 基于RabbitMQ作为消息队列,实现异步秒杀下单
  • 使用Redis的 ZSet 数据结构实现了点赞排行榜功能,使用Set 集合实现关注、共同关注功能

1.3、核心功能

用户服务

  • 短信登录(Redis替代Session实现集群共享,双拦截器保障Token刷新)

商户服务

  • 多级缓存优化(Cache Aside模式 + Redisson读写锁保障双写一致性)
  • 缓存异常处理:空值缓存防穿透、互斥锁/逻辑过期防击穿、随机TTL防雪崩

秒杀服务

  • 分布式锁(Redisson实现)解决集群环境下“一人一单”线程安全问题
  • 异步下单优化:Redis Lua脚本预检库存 + RabbitMQ消息队列异步处理订单

社交服务

  • 达人探店笔记(发布、点赞排行榜基于ZSet实现)及好友关注(Set集合实现共同关注)

2、使用 Redis 解决了在集群模式下的 Session 共享问题,使用拦截器实现了用户的登录校验和权限刷新

3、运用Cache Aside模式解决数据库与缓存的一致性问题,通过主动更新结合超时删除保证最终一致性

4、使用 Redis 对高频访问的信息进行缓存,降低数据库查询压力,解决了缓存穿透、雪崩、击穿问题

5、使用 Redis + Lua脚本实现对用户秒杀资格的预检,同时用乐观锁解决秒杀产生的超卖问题

6、使用 Redisson分布式锁解决在集群模式下一人一单的线程安全问题

7、基于RabbitMQ作为消息队列,实现异步秒杀下单

8、使用Redis的 ZSet 数据结构实现了点赞排行榜功能,使用Set 集合实现关注、共同关注功能

链接:
链接1
链接2
链接3

二、校园生活服务平台(苍穹外卖)

1、项目概述

1.1、项目简介

本项目是基于Spring Boot的校园生活服务系统,分为管理端(供校内商家使用)和用户端(微信小程序)。管理端包括员工信息、商品及分类的管理,订单状态跟踪等功能;用户端在线浏览商品,添加购物车及下单等功能。

1.2、项目亮点

  • 登录及身份验证使用JWT令牌技术,用自定义拦截器完成用户认证,通过ThreadLocal优化鉴权逻辑
  • 使用Redis缓存高频数据如同分类商品,并使用SpringCache优化代码,提高系统性能和响应速度
  • 使用Nginx用作HTTP服务器,部署静态资源,反向代理和负载均衡
  • 通过webSocket实现客户端与服务端的长连接,并实现来单提醒及客户催单等功能
  • 使用SpringTask实现订单状态的定时处理,超时自动取消订单等功能

1.3、核心功能

管理端
1、用户登录(JWT、ThreadLocal)
2、员工信息维护
3、商品管理
4、分类管理
5、订单状态跟踪
6、来单/催单提醒(webSocket实时推送)
7、Spring Cache缓存菜品信息
8、定时任务处理超时订单(Spring Task)

用户端(微信小程序)
1、微信登陆
2、商品浏览(Redis缓存)
3、购物车管理
4、下单支付

1.4 模块作用

序号模块作用
1sky-take-outmaven父工程,统一管理依赖版本,聚合其他子模块
2sky-common子模块,存放公共类,例如:工具类、常量类、异常类等
3sky-pojo子模块,存放实体类、VO、DTO等
4sky-server子模块,后端服务,存放配置文件、Controller、Service、Mapper等

2、JWT令牌+ThreadLocal

2.1、JWT登录流程

使用JWT令牌和自定义拦截器完成用户认证的流程如下:

  • 用户登录时,客户端发送用户名和密码给服务器请求令牌,服务器验证通过后生成包含用户信息的JWT令牌并返回给客户端。
  • 客户端收到JWT令牌后将其存储在本地(如localStorage或cookie),后续每次请求都在请求头中携带该令牌(如Authorization:Bearer )。
  • 服务器端的自定义拦截器会拦截所有请求,首先从请求头中提取JWT令牌并进行解析验证(包括检查令牌是否存在、签名是否有效、是否过期等),若令牌不存在或验证失败则直接返回401未认证错误。
  • 当JWT令牌验证通过后,拦截器将解析出的用户信息存储在ThreadLocal中,使本次请求的后续业务处理流程可以直接获取用户信息,避免重复解析JWT令牌。
  • 请求处理完成后,拦截器会调用remove()方法清除ThreadLocal中的用户信息,确保不会发生内存泄漏。

2.2、ThreadLocal使用过多会造成的影响?怎么解决内存泄漏的问题?

每个线程都有⼀个ThreadLocalMap的内部属性,map的key是ThreaLocal,定义为弱引用,value是强引用类型。垃圾回收的时候会⾃动回收key,但对应的 Value 仍然是强引用,且线程未结束时,ThreadLocalMap 会一直持有该 Value,导致内存泄漏。
解决⽅法:每次使⽤完ThreadLocal就调⽤它的remove()⽅法,手动将对应的键值对删除,从⽽避免内存泄漏

2.3 JWT的组成:

它由三部分组成:header(头部)、payload(载荷)、signature(签名)

  • Header(头部) 作用:描述令牌的元数据,如签名算法(如HS256、RS256)和令牌类型(固定为JWT)。
  • Payload(负载) 作用:携带实际的数据(声明),分为三类:
    预定义声明:标准字段,如 iss(签发者)、exp(过期时间)、sub(主题)等。
    公开声明:自定义公共字段,需避免冲突(建议通过IANA 注册)。
    私有声明:双方约定的自定义数据。
  • Signature(签名)作用:验证令牌的完整性和真实性。生成方式:将编码后的 Header 和 Payload 拼接后通过 Header 中指定的算法(如 HS256)和密钥进行签名。

3、Redis

3.1项目中哪里用到redis了,缓存的粒度是什么?key,value如何定义?

缓存商品 用户端小程序展示的商品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大。结果是系统响应慢、用户体验差。通过Redis来缓存商品数据,减少数据库查询操作。缓存逻辑是每个分类的商品下缓存一份数据,数据库中商品数据有变更时及时清理数据。key是分类的id,value是该分类下所有商品信息

3.2、数据库与redis如何实现的数据同步

在项目中,我们采用分布式锁策略实现数据库与Redis的数据同步。通过Redis分布式锁(如Redisson)对数据ID细粒度加锁,确保同一时间只有一个请求能修改数据;在锁内严格按"先更新数据库→再删除缓存"的顺序操作,保证后续请求必然读取最新数据;
因为有库存价格等信息所以不适合用延时双删)。
修改频率较低所以加锁性能损耗不高

4、Nginx

4.1 负载均衡:

Nginx 的负载均衡功能允许将请求分发给多个应用服务器,以均衡负载和提高系统的可扩展性和可靠性。下面是一些常用的 Nginx 负载均衡配置方法:

  • 轮询:这是默认的负载均衡策略。Nginx 将请求依次分发给每个后端服务器,确保每个服务器都能获得相同的请求数量。
  • IP 哈希(IP Hash):Nginx 使用客户端 IP地址的哈希值来决定将请求发送给哪个后端服务器。
  • 加权轮询:可以为每个后端服务器设置权重,高权重的服务器将获得更多的请求。这种方式可以根据服务器的性能和处理能力来分配负载。
    我们项目用的是轮询方式,共有2台后端服务器(一台本机,一台虚拟机)
    在nginx.conf配置:
upstream webservers{
	  server 127.0.0.1:8080 weight=90 ;
	  #server 127.0.0.1:8088 weight=10 ;
	}

4.2 反向代理与正向代理:

反向代理隐藏服务器,正向代理隐藏客户端。

  • 正向代理是客户端发送请求后通过代理服务器访问目标服务器,代理服务器代表客户端发送请求并将响应返回给客户端。正向代理隐藏了客户端的真实身份和位置信息,为客户端提供代理访问互联网的功能。
  • 反向代理是位于目标服务器和客户端之间的代理服务器,它代表服务器接收客户端的请求并将请求转发到真正的目标服务器上,并将得到的响应返回给客户端。反向代理隐藏了服务器的真实身份和位置信息,客户端只知道与反向代理进行通信,而不知道真正的服务器。

反向代理优点:

  • 提高访问速度,因为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/;
        }
 }

5、webSocket

5.1 什么是webSocket

WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

5.2、WebSocket和HTTP协议的区别?为什么不用HTTP

特性WebSocketHTTP
连接性质全双工(双向实时通信)半双工(单向请求-响应)
持久性长连接(建立后持续保持)短连接(默认每次请求后关闭)
主动推送服务端可主动推送数据服务端只能被动响应客户端请求

这两个功能对实时性要求极高,传统的HTTP请求-响应模式无法满足毫秒级推送的需求,因此我们采用WebSocket协议实现服务端主动推送,确保商家能第一时间处理订单。

5.3 WebSocket在项目中的应用场景

我们使用WebSocket实现了两个核心功能: ✅ 来单实时提醒:当用户下单并支付成功后,系统立即通知商家端有新订单。 ✅ 客户催单处理:用户点击催单按钮后,商家端实时收到催单通知,并触发语音播报。

通过WebSocket实现管理端页面和服务端保持长连接状态。当客户支付完成或者点击催单后,调用WebSocket的相关API实现服务端向客户端推送消息,客户端浏览器解析服务端推送的消息,判断是来单提醒还是客户催单,进行相应的消息提醒和语言播报

6、SpringTask

6.1、springTask怎么实现的超时自动取消订单的功能?

Spring Task(Spring 任务调度)是 Spring 框架提供的一种任务调度框架,用于执行定时任务、异步任务、任务监听、任务调度等。

苍穹外卖采用Spring Task实现订单超时自动取消功能,核心逻辑是每分钟扫描一次数据库中订单,筛选出创建时间超过15分钟且状态为"待支付"的订单,批量修改为"已取消"状态

7、数据库相关

7.1 数据库表你是怎么设计的

序号表名
1employee(员工表)
2category(分类表)
3dish(菜品表)
4dish_flavor(菜品口味表)
5setmeal(套餐表)
6setmeal_dish(套餐菜品关系表)
7user(用户表)
8address_book(地址表)
9shopping_cart(购物车表)
10orders(订单表)
11order_detail(订单明细表)

7.2 为什么用逻辑外键,而不用数据库自带的外键?

  • 减少数据库开销:物理外键约束会增加数据库在插入、更新和删除操作时的额外开销。数据库需要花费额外的时间来检查外键约束的完整性,这在高并发、大数据量的场景下可能会对性能产生明显的影响。而逻辑外键由应用程序来控制,开发人员可以根据具体业务场景,在必要时才进行关联数据的检查,避免了数据库层面不必要的检查操作,从而提高系统的整体性能
  • 适应变化:在软件开发过程中,业务需求可能会不断变化。如果使用物理外键,当表结构发生变化时,例如修改外键关联的字段类型、删除关联表中的字段等操作,可能会受到外键约束的限制,导致数据库结构的修改变得复杂和困难。而逻辑外键不存在这种限制,开发人员可以更自由地对表结构进行调整,只需要在应用程序中相应地修改逻辑外键的处理逻辑即可,提高了数据库设计的灵活性和可维护性。

8、微信相关

8.1 微信登录是怎么实现的?

  • 小程序端,调用wx.login()获取code,就是授权码。
  • 小程序端,调用wx.request()发送请求并携带code,请求开发者服务器(自己编写的后端服务)。
  • 开发者服务端,通过HttpClient向微信接口服务发送请求,并携带appId+appsecret+code三个参数。
  • 开发者服务端,接收微信接口服务返回的数据,session_key+opendId等。opendId是微信用户的唯一标识。
  • 开发者服务端,自定义登录态,生成令牌(token)和openid等数据返回给小程序端,方便后绪请求身份校验。
  • 小程序端,收到自定义登录态,存储storage。
  • 小程序端,后绪通过wx.request()发起业务请求时,携带token。
  • 开发者服务端,收到请求后,通过携带的token,解析当前登录用户的id。
  • 开发者服务端,身份校验通过后,继续相关的业务逻辑处理,最终返回业务数据。

8.2如何实现的微信支付功能?

在这里插入图片描述
完成微信支付有两个关键的步骤:
1️⃣ 就是需要在商户系统当中调用微信后台的一个下单接口,就是生成预支付交易单。

2️⃣ 就是支付成功之后微信后台会给推送消息。

9、你在项目中遇到了什么困难?

9.1处理公共字段的填充

如果都按照之前的操作方式来处理这些公共字段(创建时间,创建人id,修改时间,修改人id), 需要在每一个业务方法中进行操作, 编码相对冗余、繁琐。我们使用AOP切面编程,实现功能增强,来完成公共字段自动填充功能。

实现步骤:

1). 自定义注解 AutoFill,用于标识需要进行公共字段自动填充的方法

2). 自定义切面类 AutoFillAspect,统一拦截加入了 AutoFill 注解的方法,通过反射为公共字段赋值

3). 在 Mapper 的方法上加入 AutoFill 注解


链接:
1、链接1
2、链接2
3、链接3
4、链接4
5、链接5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2376324.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序仿淘宝拍照/照片点位识图、点位裁剪生图、图片裁剪组件、图片点位框选、裁剪生成图片,canvasToImg

实现效果 效果: 1.微信小程序仿淘宝拍照/照片点位识图、根据点位裁剪生图、图片可裁剪、图片高度可控 2.识别点位自动生成标准构图方案,支持手动微调实现像素级精准裁剪 3.可以根据接口识别的点位信息实现拍照/相册图片特征点自动识别并裁剪 实现步骤 …

Qt/C++开发监控GB28181系统/录像文件查询/录像回放/倍速播放/录像文件下载

一、前言 搞定了实时预览后,另一个功能就是录像回放,录像回放和视频点播功能完全一致,唯一的区别就是发送点播的sdp信息中携带了开始时间和结束时间,因为是录像文件,所以有这个时间,而实时视频预览这个对应…

季报中的FPGA行业:U型反转,春江水暖

上周Lattice,AMD两大厂商相继发布2025 Q1季报,尽管恢复速度各异,但同时传递出FPGA行业整体回暖的复苏信号。 5月5日,Lattice交出了“勉强及格”的答卷,报告季度营收1亿2000万,与华尔街的预期基本相符。 对于这家聚焦在中小规模器件的领先厂商而言,按照其CEO的预期,长…

嵌入式机器学习平台Edge Impulse图像分类 – 快速入门

陈拓 2025/05/08-2025/05/11 1. 简介 官方网址 https://edgeimpulse.com/ 适用于任何边缘设备的人工智能: Gateways - 网关 Sensors & Cameras - 传感器和摄像头 Docker Containers - Docker容器 MCUs, NPUs, CPUs, GPUs 构建数据集、训练模型并优化库以…

zst-2001 上午题-历年真题 计算机网络(16个内容)

网络设备 计算机网络 - 第1题 ac 计算机网络 - 第2题 d 计算机网络 - 第3题 集线器不能隔离广播域和冲突域,所以集线器就1个广播域和冲突域 交换机就是那么的炫,可以隔离冲突域,有4给冲突域,但不能隔离广播域&#xf…

使用termius连接腾讯云服务器

使用termius连接腾讯云服务器 1.下载termius termius官网 安装配置教程 这里安装的window版本> 默认安装到C盘,不建议修改路径 可以选择谷歌登录,也可以不登录,软件是免费的,试用的是付费版本,不需要点 2.配置 这里…

实景三维建模软件应用场景(众趣科技实景三维建模)

实景三维建模软件应用场景概述 实景三维建模软件,作为数字化时代的重要工具,不仅能够真实、立体、时序化地反映和表达物理世界,还为国家的基础设施建设和数字化发展提供了有力的支撑。 在测绘与地理信息领域,实景三维建模软件是构…

【Linux】基础指令(Ⅱ)

目录 1. mv指令 2. cat指令 3.echo指令 补:输出重定向 4. more指令 5. less指令 6. head指令和tail指令 7.date指令 时间戳: 8. cal指令 9. alias指令 10.grep指令 1. mv指令 语法:mv [选项]... 源文件/目录 目标文件/目录 …

【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件

问题场景: 提示:ipa是用于苹果设备安装的软件包资源 设备:iphone 13(未越狱) 安装包类型:ipa包 调试工具:hbuilderx 问题描述 提要:ios包无法安装 uniapp导出ios包无法安装 相信有小伙伴跟我一样&…

【嵌入模型与向量数据库】

目录 一、什么是向量? 二、为什么需要向量数据库? 三、向量数据库的特点 四、常见的向量数据库产品 FAISS 支持的索引类型 vs 相似度 五、常见向量相似度方法对比 六、应该用哪种 七、向量数据库的核心逻辑 🔍 示例任务:…

【东枫科技】使用LabVIEW进行NVIDIA CUDA GPU 开发

文章目录 工具包 CuLab - LabVIEW 的 GPU 工具包特性和功能功能亮点类似 LabVIEW 的 GPU 代码开发支持的功能数值类型和维数开发系统要求授权售价 工具包 CuLab - LabVIEW 的 GPU 工具包 CuLab 是一款非常直观易用的 LabVIEW 工具包,旨在加速 Nvidia GPU 上的计算密…

基于策略的强化学习方法之策略梯度(Policy Gradient)详解

在前文中,我们已经深入探讨了Q-Learning、SARSA、DQN这三种基于值函数的强化学习方法。这些方法通过学习状态值函数或动作值函数来做出决策,从而实现智能体与环境的交互。 策略梯度是一种强化学习算法,它直接对策略进行建模和优化&#xff0c…

1.Redis-key的基本命令

(一)Redis的基本类型 String,List,Set,Hash,Zset 三种特殊类型:geospatial(地理空间数据)、hyperloglog[基数估算(去重计数)]、bitmaps(位图&…

PROFIBUS DP转ModbusTCP网关模块于污水处理系统的成功应用案例解读​

在当今的工业生产领域,众多企业在生产过程中会产生大量工业废水。若这些废水未经处理直接排放,将会引发严重的工业污染问题。因此,借助科技手段对污水进行有效处理显得尤为重要。在一个污水处理系统中,往往包含来自不同厂家、不同…

电脑开机提示按f1原因分析及解决方法(6种解决方法)

经常有网友问到一个问题,我电脑开机后提示按f1怎么解决?不管理是台式电脑,还是笔记本,都有可能会遇到开机需要按F1,才能进入系统的问题,引起这个问题的原因比较多,今天小编在这里给大家列举了比较常见的几种电脑开机提示按f1的解决方法。 电脑开机提示按f1原因分析及解决…

复现:DemoGen 用于数据高效视觉运动策略学习的 合成演示生成 (RSS) 2025

https://github.com/TEA-Lab/DemoGen?tabreadme-ov-file 复现步骤很简单,按照readme配置好conda环境即可运行。 运行: cd demo_generation bash run_gen_demo.sh 等待生成: 查看data文件夹

本地部署firecrawl的两种方式,自托管和源码部署

网上资料很多 AI爬虫黑科技 firecrawl本地部署-CSDN博客 源码部署 前提条件本地安装py,node.js环境,嫌弃麻烦直接使用第二种 使用git或下载压缩包 git clone https://github.com/mendableai/firecrawl.git 设置环境参数 cd /firecrawl/apps/api 复制环境参数 …

2023年12月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析

青少年软件编程(Python)等级考试试卷(六级) 分数:100 题数:38 一、单选题(共25题,共50分) 1. 运行以下程序,输出的结果是?( ) class A(): …

Spring @Lazy注解详解

文章目录 Lazy注解主要作用工作原理使用方法注意事项总结 Lazy注解主要作用 首先,让我们看看Lazy注解的源码,截图如下: 源码注释翻译如下 通过源码,我们可以看到:Lazy注解是一个标记注解,用于标记 bean会…

中国品牌日 | 以科技创新为引领,激光院“风采”品牌建设结硕果

品牌,作为企业不可或缺的隐形财富,在当今竞争激烈的市场环境中,其构建与强化已成为推动企业持续繁荣的关键基石。为了更好地保护自主研发产品,激光院激光公司于2020年3月7日正式注册“风采”商标,创建拥有自主知识产权…