1. 项目概述
校园跑腿网站是一个基于SpringBoot+Vue技术栈开发的B/S架构应用,旨在为高校学生提供便捷的跑腿服务交易平台。这个项目让我想起了大三时帮室友代取快递的经历——当时如果有这样一个平台,就能省去不少麻烦。系统采用前后端分离设计,后端使用SpringBoot提供RESTful API,前端采用Vue.js构建响应式界面,数据库选用MySQL存储业务数据。
提示:校园跑腿类应用的核心价值在于解决"最后一公里"问题,将学生的碎片化时间转化为服务资源。这类系统通常需要特别关注交易安全性和即时通讯功能。
2. 技术选型解析
2.1 后端技术栈
SpringBoot 2.7.x作为后端框架的选择主要基于以下考量:
- 自动配置特性大幅减少XML配置,快速构建独立运行的生产级应用
- 内嵌Tomcat服务器,无需额外部署WAR包
- 完善的Starter依赖管理,整合MyBatis、Redis等组件只需添加对应依赖
- Actuator模块提供健康检查、指标监控等运维功能
java复制// 典型SpringBoot启动类配置
@SpringBootApplication
@MapperScan("com.campus.run.mapper")
public class CampusRunApplication {
public static void main(String[] args) {
SpringApplication.run(CampusRunApplication.class, args);
}
}
2.2 前端技术栈
Vue 3.x的优势体现在:
- 组合式API更利于逻辑复用,相比Options API更灵活
- 基于Proxy的响应式系统,性能优于Vue 2的defineProperty
- 单文件组件(SFC)将模板、逻辑和样式封装在.vue文件中
- 丰富的生态系统(Vue Router、Pinia、Element Plus等)
javascript复制// Vue3组合式API示例
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">点击次数: {{ count }}</button>
</template>
3. 系统架构设计
3.1 B/S三层架构
- 表现层:Vue构建的Web界面,通过Axios与后端交互
- 业务逻辑层:SpringBoot处理核心业务,包括:
- 订单管理
- 用户认证
- 支付对接
- 消息通知
- 数据访问层:MyBatis-Plus操作MySQL,Redis缓存热点数据
3.2 数据库设计
关键表结构设计原则:
- 用户表(user):采用垂直分表,将基础信息与隐私信息分离
- 订单表(order):包含状态机设计(待接单、进行中、已完成等)
- 跑腿任务表(task):记录任务详情、报酬、时限等
- 评价表(review):采用星评+文字评价的组合模式
sql复制CREATE TABLE `order` (
`id` bigint NOT NULL AUTO_INCREMENT,
`order_no` varchar(32) NOT NULL COMMENT '订单编号',
`user_id` bigint NOT NULL COMMENT '下单用户ID',
`runner_id` bigint DEFAULT NULL COMMENT '接单跑腿员ID',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态',
`total_amount` decimal(10,2) NOT NULL COMMENT '订单总金额',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_order_no` (`order_no`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4. 核心功能实现
4.1 用户认证模块
采用JWT+Spring Security的安全方案:
- 密码存储使用BCrypt强哈希处理
- 登录成功返回包含用户角色的JWT令牌
- 前端将Token存储在localStorage并设置Axios全局拦截器
java复制// 密码加密工具类
public class PasswordUtil {
private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
public static String encrypt(String rawPassword) {
return encoder.encode(rawPassword);
}
public static boolean matches(String rawPassword, String encodedPassword) {
return encoder.matches(rawPassword, encodedPassword);
}
}
4.2 订单状态机
订单生命周期管理的关键点:
- 使用状态模式实现订单状态流转
- 每个状态变更记录操作日志
- 超时未接单自动取消机制
java复制// 订单状态枚举定义
public enum OrderStatus {
PENDING(0, "待接单"),
ACCEPTED(1, "已接单"),
IN_PROGRESS(2, "进行中"),
COMPLETED(3, "已完成"),
CANCELLED(-1, "已取消");
private final int code;
private final String desc;
// 构造方法、getter省略
}
4.3 即时通讯方案
基于WebSocket的实时通讯实现:
- 使用Spring的WebSocket API建立全双工通信
- 消息类型包括:
- 订单状态变更通知
- 跑腿员接单提醒
- 用户与跑腿员的聊天消息
- 离线消息存储到MySQL,登录后拉取
java复制@Controller
public class MessageWebSocketHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
// 处理收到的消息
String payload = message.getPayload();
// 业务逻辑处理...
}
}
5. 开发经验与优化技巧
5.1 性能优化实践
-
缓存策略:
- 使用Redis缓存用户基本信息(TTL 30分钟)
- 热门跑腿任务列表缓存5分钟
- 采用Cache-Aside模式保证一致性
-
SQL优化:
- 为所有查询条件添加合适索引
- 大表查询强制指定索引
- 避免SELECT *,只查询必要字段
-
前端优化:
- 路由懒加载减少首屏资源
- 图片使用WebP格式+CDN加速
- 长列表使用虚拟滚动
5.2 安全防护措施
-
输入验证:
- 前端使用VeeValidate进行基础校验
- 后端Spring Validation做最终校验
- 防XSS:Jackson配置HTML转义
-
接口防护:
- 敏感接口限流(如登录接口)
- 关键操作需要二次确认
- 支付接口签名验证
-
日志审计:
- 记录关键操作日志
- 使用MDC实现请求链路追踪
- 敏感数据脱敏存储
6. 典型问题解决方案
6.1 订单并发问题
场景:多个跑腿员同时抢单可能导致超接
解决方案:
- 使用数据库乐观锁(version字段)
- Redis分布式锁控制抢单操作
- 前端限制按钮点击频率
java复制public boolean acceptOrder(Long orderId, Long runnerId) {
// 使用Redis分布式锁
String lockKey = "order:accept:" + orderId;
try {
boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
if (!locked) {
throw new BusinessException("操作太频繁,请稍后再试");
}
// 核心业务逻辑...
} finally {
redisTemplate.delete(lockKey);
}
}
6.2 地理位置处理
需求:显示附近的跑腿员
解决方案:
- 使用MySQL空间索引存储坐标
- Redis GEO计算附近的人
- 前端H5 Geolocation API获取用户位置
sql复制-- 用户表添加地理位置字段
ALTER TABLE user ADD COLUMN location POINT NOT NULL SRID 4326;
-- 创建空间索引
CREATE SPATIAL INDEX idx_location ON user(location);
-- 查询5公里内的跑腿员
SELECT id, name,
ST_Distance_Sphere(location, POINT(116.404, 39.915)) as distance
FROM user
WHERE ST_Distance_Sphere(location, POINT(116.404, 39.915)) <= 5000
ORDER BY distance;
7. 部署与监控
7.1 生产环境部署
-
后端部署:
- 使用Docker打包SpringBoot应用
- Nginx负载均衡多个实例
- 配置JVM参数(堆内存、GC策略)
-
前端部署:
- Vue项目打包为静态文件
- Nginx配置gzip压缩
- 开启HTTP/2提升加载速度
-
数据库部署:
- 主从复制保证高可用
- 定期备份策略
- 慢查询监控优化
7.2 系统监控方案
-
SpringBoot Actuator:
- 暴露/actuator/health端点
- 自定义健康检查指标
- Prometheus采集指标数据
-
日志系统:
- ELK收集分析日志
- 关键错误触发告警
- 业务日志单独存储
-
APM工具:
- SkyWalking追踪调用链路
- 定位性能瓶颈
- 可视化服务依赖关系
在项目开发过程中,最大的收获是对分布式系统常见问题的实战经验。比如在实现抢单功能时,最初没有考虑并发问题导致测试环境出现超接现象,后来通过引入Redis分布式锁才彻底解决。这也让我明白,校园应用虽然规模不大,但仍然需要考虑生产环境可能遇到的各种边界情况。