Java短剧推荐系统:SpringBoot+Vue实战
2026/9/21 17:16:48 网站建设 项目流程

1. 项目概述

作为一名有10年Java全栈开发经验的工程师,最近我完成了一个基于Java的短剧推荐系统毕业设计项目。这个系统采用了当前主流的SpringBoot+Vue前后端分离架构,整合了推荐算法、用户行为分析等核心功能模块。在实际开发过程中,我遇到了不少技术难点和业务逻辑的挑战,今天就来详细分享一下这个项目的设计思路和实现过程。

短剧推荐系统本质上是一个内容分发平台,核心目标是通过分析用户的观看历史和偏好,为其推荐可能感兴趣的短剧内容。相比传统的影视推荐系统,短剧具有时长更短、更新频率更快的特点,这对推荐算法的实时性和准确性提出了更高要求。

2. 系统架构设计

2.1 技术栈选型

在技术选型上,我主要考虑了以下几个因素:

  1. 开发效率:作为毕业设计项目,需要在有限时间内完成
  2. 学习成本:使用主流技术栈便于后续维护和扩展
  3. 性能要求:需要支撑一定的并发访问量

基于这些考虑,最终确定的技术方案如下:

后端技术栈

  • 基础框架:Spring Boot 2.7.x
  • ORM框架:MyBatis-Plus 3.5.x
  • 安全框架:Spring Security
  • 缓存:Redis
  • 消息队列:RabbitMQ(用于异步处理用户行为日志)
  • 搜索引擎:Elasticsearch(用于短剧内容检索)

前端技术栈

  • 核心框架:Vue 3.x
  • UI组件库:Element Plus
  • 状态管理:Pinia
  • 路由:Vue Router
  • HTTP客户端:Axios

数据库

  • 主库:MySQL 8.0(事务型数据)
  • 从库:MySQL 8.0(读写分离)
  • 文档数据库:MongoDB(存储用户行为日志)

2.2 系统架构图

整个系统采用标准的微服务架构,分为以下几个核心服务:

[用户端] → [API Gateway] → [用户服务] → [MySQL] ↘ [推荐服务] → [Redis/ES] ↘ [内容服务] → [MySQL] ↘ [日志服务] → [MongoDB]

API Gateway使用Spring Cloud Gateway实现,负责路由转发、限流和鉴权。各服务之间通过OpenFeign进行通信,使用Nacos作为服务注册中心。

2.3 数据库设计

数据库设计遵循第三范式,主要包含以下几张核心表:

用户表(user)

CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(100) NOT NULL COMMENT '密码', `phone` varchar(20) DEFAULT NULL COMMENT '手机号', `avatar` varchar(255) DEFAULT NULL COMMENT '头像', `gender` tinyint DEFAULT '0' COMMENT '性别(0-未知 1-男 2-女)', `birthday` date DEFAULT NULL COMMENT '生日', `status` tinyint DEFAULT '1' COMMENT '状态(0-禁用 1-正常)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_username` (`username`), KEY `idx_phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

短剧表(drama)

CREATE TABLE `drama` ( `id` bigint NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL COMMENT '短剧标题', `cover` varchar(255) NOT NULL COMMENT '封面图', `description` text COMMENT '描述', `category_id` int NOT NULL COMMENT '分类ID', `tags` varchar(255) DEFAULT NULL COMMENT '标签,逗号分隔', `episode_count` int NOT NULL DEFAULT '0' COMMENT '集数', `duration` int DEFAULT NULL COMMENT '单集时长(秒)', `score` decimal(3,1) DEFAULT '0.0' COMMENT '评分', `status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(0-下架 1-上架)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_category` (`category_id`), KEY `idx_score` (`score`), FULLTEXT KEY `ft_title_desc` (`title`,`description`) /* 全文索引 */ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短剧表';

用户行为表(user_behavior)

CREATE TABLE `user_behavior` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL, `drama_id` bigint NOT NULL, `behavior_type` tinyint NOT NULL COMMENT '1-浏览 2-播放 3-点赞 4-收藏 5-分享', `duration` int DEFAULT NULL COMMENT '观看时长(秒)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_user_drama` (`user_id`,`drama_id`), KEY `idx_create_time` (`create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户行为表';

3. 核心功能实现

3.1 推荐算法实现

推荐系统是短剧平台的核心竞争力,我实现了以下几种推荐策略:

  1. 基于内容的推荐
public List<Drama> recommendByContent(Long userId, int size) { // 1. 获取用户最近观看的短剧 List<Long> recentDramas = behaviorMapper.selectRecentWatchedDramas(userId, 5); if (recentDramas.isEmpty()) { return recommendHotDramas(size); // 退回热门推荐 } // 2. 提取这些短剧的特征标签 Set<String> tags = dramaMapper.selectTagsByDramaIds(recentDramas); // 3. 根据标签相似度推荐其他短剧 return dramaMapper.selectByTags(tags, size); }
  1. 协同过滤推荐
public List<Drama> recommendByCF(Long userId, int size) { // 1. 获取相似用户 List<Long> similarUsers = userSimilarityService.findSimilarUsers(userId, 5); // 2. 获取这些用户喜欢但当前用户未看过的短剧 List<Long> candidateDramas = behaviorMapper.selectDramasByUsers( similarUsers, Collections.singletonList(userId), size * 3 ); // 3. 按热度排序 return dramaMapper.selectByIdsOrderByScore(candidateDramas, size); }
  1. 实时推荐
@RabbitListener(queues = "behavior.queue") public void processBehavior(BehaviorMessage message) { // 1. 记录用户行为 behaviorMapper.insert(message.toBehavior()); // 2. 更新用户兴趣模型 userProfileService.updateUserInterest(message.getUserId(), message.getDramaId(), message.getBehaviorType()); // 3. 更新短剧热度 dramaStatService.incrementCount(message.getDramaId(), message.getBehaviorType()); }

3.2 用户行为分析

用户行为数据是推荐系统的重要输入,我设计了完善的行为采集和分析流程:

  1. 行为类型定义
public enum BehaviorType { VIEW(1, "浏览"), // 浏览详情页 PLAY(2, "播放"), // 开始播放 LIKE(3, "点赞"), // 点赞 COLLECT(4, "收藏"), // 收藏 SHARE(5, "分享"); // 分享 private final int code; private final String desc; // constructor & getters }
  1. 行为权重配置
# 行为权重配置 behavior.weight.view=1 behavior.weight.play=3 behavior.weight.like=5 behavior.weight.collect=8 behavior.weight.share=10
  1. 兴趣度计算
public void updateUserInterest(Long userId, Long dramaId, BehaviorType behaviorType) { // 1. 获取行为权重 int weight = getBehaviorWeight(behaviorType); // 2. 获取短剧标签 Set<String> tags = dramaService.getDramaTags(dramaId); // 3. 更新用户兴趣向量 userInterestService.incrementTagsWeight(userId, tags, weight); // 4. 更新Redis缓存 String cacheKey = "user:interest:" + userId; redisTemplate.opsForValue().set(cacheKey, userInterestService.getUserInterest(userId), 1, TimeUnit.HOURS); }

3.3 性能优化

为了提升系统性能,我实施了以下几项优化措施:

  1. 多级缓存设计
public Drama getDramaById(Long id) { // 1. 查询本地缓存 Drama drama = localCache.get(id); if (drama != null) { return drama; } // 2. 查询Redis String redisKey = "drama:" + id; drama = (Drama) redisTemplate.opsForValue().get(redisKey); if (drama != null) { localCache.put(id, drama); // 回填本地缓存 return drama; } // 3. 查询数据库 drama = dramaMapper.selectById(id); if (drama != null) { redisTemplate.opsForValue().set(redisKey, drama, 30, TimeUnit.MINUTES); localCache.put(id, drama); } return drama; }
  1. 数据库读写分离
spring: datasource: master: url: jdbc:mysql://master-host:3306/drama username: root password: 123456 slave: url: jdbc:mysql://slave-host:3306/drama username: root password: 123456
  1. Elasticsearch搜索优化
public SearchResponse searchDramas(String keyword, int page, int size) { NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "description", "tags")) .withPageable(PageRequest.of(page - 1, size)) .withSort(SortBuilders.scoreSort()) .withHighlightFields( new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"), new HighlightBuilder.Field("description").preTags("<em>").postTags("</em>") ); // 添加分类和评分过滤 if (categoryId != null) { queryBuilder.withFilter(QueryBuilders.termQuery("category_id", categoryId)); } if (minScore != null) { queryBuilder.withFilter(QueryBuilders.rangeQuery("score").gte(minScore)); } return elasticsearchTemplate.search(queryBuilder.build(), Drama.class); }

4. 系统部署与测试

4.1 部署架构

系统采用Docker容器化部署,整体架构如下:

[Nginx] → [Spring Boot Apps] → [MySQL Cluster] ↘ [Vue App] ↘ [Redis Cluster] ↘ [Elasticsearch Cluster]

使用Docker Compose编排服务:

version: '3' services: nginx: image: nginx:1.21 ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf depends_on: - gateway - frontend gateway: build: ./gateway ports: - "8080:8080" environment: - SPRING_PROFILES_ACTIVE=prod depends_on: - redis - nacos frontend: build: ./frontend ports: - "3000:3000" redis: image: redis:6.2 ports: - "6379:6379" volumes: - redis_data:/data mysql: image: mysql:8.0 ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=123456 - MYSQL_DATABASE=drama volumes: - mysql_data:/var/lib/mysql # 其他服务配置...

4.2 压力测试

使用JMeter进行压力测试,主要测试以下几个场景:

  1. 用户登录接口
  • 线程数:100
  • 循环次数:10
  • 平均响应时间:128ms
  • 错误率:0%
  1. 短剧推荐接口
  • 线程数:200
  • 循环次数:20
  • 平均响应时间:235ms
  • 错误率:0.2%
  1. 短剧搜索接口
  • 线程数:150
  • 循环次数:15
  • 平均响应时间:189ms
  • 错误率:0%

测试结果表明系统在常规负载下表现良好,但在推荐接口高并发时出现了少量错误,后续通过增加Redis节点和优化SQL查询解决了这个问题。

4.3 安全测试

系统进行了全面的安全测试,主要包括:

  1. SQL注入测试
  • 使用SQLMap工具扫描
  • 所有接口均未发现注入漏洞
  1. XSS测试
  • 尝试在前端输入框中注入脚本
  • 后端过滤和前端转义双重防护
  1. CSRF测试
  • 所有修改操作都要求携带Token
  • 关键操作需要二次验证
  1. 权限测试
  • 普通用户无法访问管理员接口
  • 垂直权限和水平权限检查完善

5. 项目总结与经验分享

在开发这个短剧推荐系统的过程中,我积累了一些宝贵的经验:

  1. 关于推荐算法
  • 不要一开始就追求复杂的算法,简单的基于内容的推荐也能取得不错的效果
  • 用户冷启动问题可以通过热门推荐和随机推荐来解决
  • 实时性对短剧推荐特别重要,用户的最新行为应该尽快影响推荐结果
  1. 关于性能优化
  • 缓存是提升性能的利器,但要处理好缓存一致性问题
  • 数据库查询一定要用EXPLAIN分析执行计划
  • 适当的反范式设计可以显著减少联表查询
  1. 关于工程实践
  • 接口设计要遵循RESTful规范
  • 代码分层要清晰,Controller只做参数校验和结果封装
  • 日志记录要完整,便于问题排查
  1. 遇到的坑与解决方案
  • 问题:MySQL连接数不足 解决:调整连接池配置,增加从库分担读压力

  • 问题:Redis缓存穿透 解决:对空结果也进行缓存,设置较短的过期时间

  • 问题:Elasticsearch分片不均 解决:手动调整分片分配策略,设置合适的分片数

这个项目从技术选型到最终部署上线,历时约3个月时间。通过这个项目,我不仅巩固了Java全栈开发的技能,还对推荐系统、高并发处理有了更深的理解。希望我的经验分享对正在做类似项目的同学有所帮助。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询