1. 项目概述
作为一名从事餐饮行业信息化建设多年的开发者,我深知当前餐饮点评领域存在的痛点:信息碎片化、评价可信度低、商家与消费者互动不足。基于这些观察,我决定开发一个基于Spring Boot的在线餐饮点评系统,整合点评、订餐、商家管理等功能于一体。
这个系统采用了主流的技术栈:
- 后端:Spring Boot 2.7 + MyBatis Plus
- 前端:Vue.js 3 + Element Plus
- 数据库:MySQL 8.0
- 缓存:Redis 6.2
- 搜索:Elasticsearch 7.17
提示:系统采用前后端分离架构,通过RESTful API进行数据交互,保证了系统的可扩展性和维护性。
2. 系统架构设计
2.1 技术选型考量
选择Spring Boot作为后端框架主要基于以下考虑:
- 快速开发:自动配置和起步依赖大大减少了样板代码
- 生态丰富:与MyBatis、Redis等组件集成简单
- 性能稳定:内嵌Tomcat,成熟的线程模型
- 社区支持:遇到问题容易找到解决方案
数据库选择MySQL 8.0是因为:
- 对事务支持完善
- JSON数据类型便于存储半结构化数据
- 窗口函数等高级特性便于数据分析
2.2 系统分层架构
系统采用经典的三层架构:
表现层 → 业务逻辑层 → 数据访问层每层的职责明确:
- 表现层:处理HTTP请求,参数校验
- 业务层:核心业务逻辑实现
- 数据层:数据库操作和缓存处理
2.3 微服务化设计
虽然当前是单体架构,但在设计时考虑了未来微服务化的可能:
- 按功能模块分包,边界清晰
- 使用Feign风格的内部服务调用
- 数据库按模块分库设计
3. 核心功能实现
3.1 用户认证模块
采用JWT+Redis实现无状态认证:
// JWT生成示例 public String generateToken(User user) { return Jwts.builder() .setSubject(user.getUsername()) .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) .signWith(SignatureAlgorithm.HS512, SECRET) .compact(); }安全措施:
- 密码加盐哈希存储
- 敏感接口限流
- XSS和SQL注入防护
3.2 餐厅信息管理
采用Elasticsearch实现全文搜索:
// 餐厅搜索实现 public Page<Restaurant> search(String keyword, String location, Pageable pageable) { NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); if (StringUtils.hasText(keyword)) { queryBuilder.withQuery(QueryBuilders.multiMatchQuery(keyword, "name", "description")); } if (StringUtils.hasText(location)) { queryBuilder.withFilter(QueryBuilders.termQuery("location", location)); } return restaurantRepository.search(queryBuilder.build(), pageable); }3.3 订单系统设计
订单状态机设计:
待支付 → 已支付 → 制作中 → 配送中 → 已完成 ↘ 已取消使用Redis实现库存扣减:
public boolean reduceStock(Long dishId, int quantity) { String key = "dish_stock:" + dishId; Long value = redisTemplate.opsForValue().decrement(key, quantity); if (value != null && value >= 0) { return true; } else { // 库存不足,回滚 redisTemplate.opsForValue().increment(key, quantity); return false; } }4. 性能优化实践
4.1 缓存策略
采用多级缓存架构:
- 本地缓存(Caffeine):高频访问的基础数据
- 分布式缓存(Redis):共享数据和会话
- 数据库缓存:查询结果缓存
缓存更新策略:
- 写穿透:先更新DB再删除缓存
- 读穿透:缓存未命中时从DB加载
4.2 数据库优化
- 索引优化:为高频查询字段添加组合索引
- 分表策略:订单表按月分表
- 读写分离:主库写,从库读
4.3 高并发处理
- 秒杀场景使用Redis+Lua实现原子扣减
- 热点数据使用本地缓存
- 异步处理评价统计等非实时需求
5. 安全防护措施
5.1 数据安全
- 敏感字段加密存储
- 数据库定期备份
- 操作日志完整记录
5.2 接口安全
- 参数签名验证
- 频率限制
- 权限细粒度控制
5.3 支付安全
- 支付回调验签
- 订单状态一致性检查
- 对账机制
6. 部署方案
6.1 容器化部署
使用Docker Compose编排服务:
version: '3' services: app: image: restaurant-review:latest ports: - "8080:8080" depends_on: - redis - mysql redis: image: redis:6.2 ports: - "6379:6379" mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: password ports: - "3306:3306"6.2 监控方案
- Prometheus + Grafana监控系统指标
- ELK收集分析日志
- SkyWalking链路追踪
7. 踩坑经验分享
7.1 事务一致性
在分布式环境下保证数据一致性是个挑战。我们最终采用:
- 本地消息表实现最终一致性
- 关键操作添加补偿机制
- 定期对账检查
7.2 评价排序算法
单纯的按时间或评分排序效果不好,最终采用混合排序:
综合评分 = 基础评分 × 时间衰减因子 + 用户权重其中:
- 时间衰减因子:1/(1+天数×0.1)
- 用户权重:根据用户历史评价质量计算
7.3 图片处理
用户上传的餐厅图片需要处理:
- 压缩:减少存储和带宽消耗
- 水印:防止盗用
- 内容审核:过滤违规图片
使用Thumbnailator库实现:
Thumbnails.of(inputStream) .size(800, 600) .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(watermarkFile), 0.5f) .outputQuality(0.8) .toOutputStream(outputStream);8. 未来优化方向
- 引入推荐算法提升个性化体验
- 增加社交功能增强用户粘性
- 开发小程序端扩大用户覆盖
- 接入更多第三方服务(如地图、支付)
在实际开发过程中,最大的体会是系统设计要预留扩展性。餐饮行业变化快,需求迭代频繁,良好的架构设计能大大降低后期维护成本。另外,性能优化要基于真实数据,过早优化往往是浪费资源。