基于Spring Boot的商品推荐设计与实现

📅 2026/8/24 2:15:43
基于Spring Boot的商品推荐设计与实现
一、 技术栈与背景意义1.1 技术栈本系统采用前后端分离架构主要技术栈如下后端框架Spring Boot 3.x Spring MVC Spring Data JPA数据存储MySQL 8.0关系型数据、Redis 7.x缓存与实时特征推荐算法协同过滤基于用户/基于物品、基于内容的推荐、混合推荐策略消息队列RabbitMQ / Kafka用于异步处理用户行为日志搜索与向量化Elasticsearch 8.x商品搜索、可选集成 Milvus / FAISS向量相似度计算部署与监控Docker Kubernetes、Prometheus Grafana前端技术Vue 3 / React Axios Element Plus / Ant Design1.2 背景与意义在电商、内容平台、社交应用等场景中商品/内容推荐系统是提升用户体验、增加用户粘性和转化率的核心引擎。传统的人工运营或简单规则推荐已无法满足海量商品和个性化需求。基于Spring Boot构建推荐系统的意义在于快速迭代Spring Boot的自动配置和起步依赖极大简化了微服务开发便于算法工程师与后端工程师协作快速实现和部署推荐模型。高可扩展性微服务架构允许推荐服务独立部署、弹性伸缩轻松应对流量高峰。生态整合Spring生态与大数据组件如Spark、Flink、消息队列、缓存、数据库等无缝集成便于构建从数据采集、特征工程、模型训练到在线服务的完整Pipeline。工程化落地将机器学习算法如协同过滤、深度学习排序模型封装成RESTful API便于前端调用实现从离线实验到在线AB测试的完整闭环。二、 核心设计与实现2.1 系统架构设计系统采用分层架构主要模块如下数据采集层通过前端埋点、Nginx日志、消息队列收集用户行为点击、浏览、购买、收藏。特征存储层用户画像、商品特征、实时行为特征存储在Redis和特征数据库中。召回层基于多种策略协同过滤、热门商品、基于内容从全量商品池中快速筛选出数百个候选商品。排序层使用更复杂的模型如LR、GBDT、深度学习模型对召回结果进行精排输出最终Top-N推荐列表。服务层Spring Boot构建的REST API对外提供推荐接口。2.2 核心代码实现2.2.1 数据模型定义// 用户实体 Entity Table(name user) Data public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String username; private Integer age; private String gender; // 用户特征向量JSON存储或单独表 Column(columnDefinition json) private String featureVector; private LocalDateTime createTime; } // 商品实体 Entity Table(name product) Data public class Product { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String name; private String category; private BigDecimal price; Column(columnDefinition text) private String description; // 商品特征向量用于内容推荐 Column(columnDefinition json) private String featureVector; private Integer salesCount; private LocalDateTime createTime; } // 用户-商品交互记录行为日志 Entity Table(name user_interaction) Data public class UserInteraction { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private Long userId; private Long productId; // 行为类型VIEW, CLICK, PURCHASE, COLLECT private String actionType; private Integer score; // 隐式反馈分数如浏览1购买5 private LocalDateTime actionTime; }2.2.2 协同过滤推荐服务Service Slf4j public class CollaborativeFilteringService { Autowired private UserInteractionRepository interactionRepository; Autowired private ProductRepository productRepository; Autowired private RedisTemplatelt;String, Objectgt; redisTemplate; /** 基于用户的协同过滤UserCF 找到与目标用户兴趣相似的用户群 从相似用户喜欢的商品中推荐目标用户未接触过的商品 */ public Listlt;Productgt; recommendByUserCF(Long userId, int topN) { // 1. 获取目标用户的历史交互商品 Listlt;Longgt; targetUserProductIds interactionRepository.findProductIdsByUserId(userId); // 2. 计算用户相似度这里简化为基于共同交互商品数量的余弦相似度 Maplt;Long, Doublegt; userSimilarityMap new HashMaplt;gt;(); // ... 省略相似度计算具体实现可从Redis缓存中读取预计算的用户相似度矩阵 // 3. 获取最相似的K个用户 Listlt;Longgt; similarUserIds userSimilarityMap.entrySet().stream() .sorted(Map.Entry.lt;Long, Doublegt;comparingByValue().reversed()) .limit(10) .map(Map.Entry::getKey) .collect(Collectors.toList()); // 4. 聚合相似用户喜欢的商品并过滤掉目标用户已交互过的 Maplt;Long, Doublegt; productScoreMap new HashMaplt;gt;(); for (Long similarUserId : similarUserIds) { Listlt;UserInteractiongt; interactions interactionRepository.findByUserId(similarUserId); for (UserInteraction interaction : interactions) { Long productId interaction.getProductId(); if (!targetUserProductIds.contains(productId)) { // 根据行为类型和用户相似度加权计算推荐分数 double score interaction.getScore() * userSimilarityMap.get(similarUserId); productScoreMap.put(productId, productScoreMap.getOrDefault(productId, 0.0) score); } } } // 5. 按分数排序返回TopN商品 return productScoreMap.entrySet().stream() .sorted(Map.Entry.lt;Long, Doublegt;comparingByValue().reversed()) .limit(topN) .map(entry -gt; productRepository.findById(entry.getKey()).orElse(null)) .filter(Objects::nonNull) .collect(Collectors.toList()); } /** 基于物品的协同过滤ItemCF 计算商品之间的相似度 根据用户历史喜欢的商品推荐相似的商品 */ public Listlt;Productgt; recommendByItemCF(Long userId, int topN) { // 从缓存或数据库中获取用户历史交互的正向商品如购买、收藏 Listlt;Longgt; userLikedProductIds interactionRepository.findLikedProductIdsByUserId(userId); // 商品相似度矩阵可离线计算后存入Redis String cacheKey item_similarity_matrix; Maplt;String, Doublegt; similarityMatrix (Maplt;String, Doublegt;) redisTemplate.opsForValue().get(cacheKey); Maplt;Long, Doublegt; candidateProductScore new HashMaplt;gt;(); for (Long likedProductId : userLikedProductIds) { // 获取与该商品最相似的商品列表 Maplt;Long, Doublegt; similarProducts getSimilarProducts(likedProductId, similarityMatrix); for (Map.Entrylt;Long, Doublegt; entry : similarProducts.entrySet()) { Long candidateId entry.getKey(); if (!userLikedProductIds.contains(candidateId)) { candidateProductScore.put(candidateId, candidateProductScore.getOrDefault(candidateId, 0.0) entry.getValue()); } } } // 排序并返回 return candidateProductScore.entrySet().stream() .sorted(Map.Entry.lt;Long, Doublegt;comparingByValue().reversed()) .limit(topN) .map(entry -gt; productRepository.findById(entry.getKey()).orElse(null)) .filter(Objects::nonNull) .collect(Collectors.toList()); } private Maplt;Long, Doublegt; getSimilarProducts(Long productId, Maplt;String, Doublegt; similarityMatrix) { // 实现从相似度矩阵中查询逻辑 return new HashMaplt;gt;(); } }2.2.3 推荐API控制器RestController RequestMapping(/api/recommend) Slf4j public class RecommendController { Autowired private CollaborativeFilteringService cfService; Autowired private ContentBasedService contentBasedService; Autowired private RealTimeRecommendService realTimeService; /** 获取个性化推荐列表混合策略 */ GetMapping(/personalized/{userId}) public ResponseEntitylt;Listlt;ProductDTOgt;gt; getPersonalizedRecommendations( PathVariable Long userId, RequestParam(defaultValue 10) int topN, RequestParam(defaultValue hybrid) String strategy) { Listlt;Productgt; recommendations; switch (strategy) { case user_cf: recommendations cfService.recommendByUserCF(userId, topN); break; case item_cf: recommendations cfService.recommendByItemCF(userId, topN); break; case content: recommendations contentBasedService.recommendByContent(userId, topN); break; case hybrid: // 混合推荐加权融合多种策略的结果 recommendations hybridRecommend(userId, topN); break; default: recommendations cfService.recommendByUserCF(userId, topN); } // 注入实时行为反馈实时层 recommendations realTimeService.adjustByRealTimeBehavior(userId, recommendations); Listlt;ProductDTOgt; dtos recommendations.stream() .map(this::convertToDTO) .collect(Collectors.toList()); return ResponseEntity.ok(dtos); } private Listlt;Productgt; hybridRecommend(Long userId, int topN) { // 实现混合推荐逻辑例如加权分数融合、级联、切换等 return cfService.recommendByUserCF(userId, topN); } private ProductDTO convertToDTO(Product product) { ProductDTO dto new ProductDTO(); dto.setId(product.getId()); dto.setName(product.getName()); dto.setCategory(product.getCategory()); dto.setPrice(product.getPrice()); dto.setDescription(product.getDescription()); dto.setSalesCount(product.getSalesCount()); return dto; } }三、 总结与展望本文介绍了基于Spring Boot的商品推荐系统的技术栈、背景意义以及核心代码实现。一个完整的推荐系统远不止于此还需要考虑特征工程如何构建有效的用户和商品特征。离线训练与在线更新模型如何定期更新以及如何做在线学习。评估与AB测试设计科学的评估指标如CTR、转化率和AB测试框架持续优化推荐效果。冷启动问题针对新用户和新商品设计有效的冷启动策略如热门推荐、基于注册信息的推荐。Spring Boot为推荐系统的工程化落地提供了强大的支持使得算法工程师可以更专注于模型和策略而无需过度纠结于服务框架的复杂性。一、 技术栈与背景意义1.1 技术栈本系统采用前后端分离架构主要技术栈如下后端框架Spring Boot 3.x Spring MVC Spring Data JPA数据存储MySQL 8.0关系型数据、Redis 7.x缓存与实时特征推荐算法协同过滤基于用户/基于物品、基于内容的推荐、混合推荐策略消息队列RabbitMQ / Kafka用于异步处理用户行为日志搜索与向量化Elasticsearch 8.x商品搜索、可选集成 Milvus / FAISS向量相似度计算部署与监控Docker Kubernetes、Prometheus Grafana前端技术Vue 3 / React Axios Element Plus / Ant Design1.2 背景与意义在电商、内容平台、社交应用等场景中商品/内容推荐系统是提升用户体验、增加用户粘性和转化率的核心引擎。传统的人工运营或简单规则推荐已无法满足海量商品和个性化需求。基于Spring Boot构建推荐系统的意义在于快速迭代Spring Boot的自动配置和起步依赖极大简化了微服务开发便于算法工程师与后端工程师协作快速实现和部署推荐模型。高可扩展性微服务架构允许推荐服务独立部署、弹性伸缩轻松应对流量高峰。生态整合Spring生态与大数据组件如Spark、Flink、消息队列、缓存、数据库等无缝集成便于构建从数据采集、特征工程、模型训练到在线服务的完整Pipeline。工程化落地将机器学习算法如协同过滤、深度学习排序模型封装成RESTful API便于前端调用实现从离线实验到在线AB测试的完整闭环。二、 核心设计与实现2.1 系统架构设计系统采用分层架构主要模块如下数据采集层通过前端埋点、Nginx日志、消息队列收集用户行为点击、浏览、购买、收藏。特征存储层用户画像、商品特征、实时行为特征存储在Redis和特征数据库中。召回层基于多种策略协同过滤、热门商品、基于内容从全量商品池中快速筛选出数百个候选商品。排序层使用更复杂的模型如LR、GBDT、深度学习模型对召回结果进行精排输出最终Top-N推荐列表。服务层Spring Boot构建的REST API对外提供推荐接口。2.2 核心代码实现2.2.1 数据模型定义// 用户实体 Entity Table(name user) Data public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String username; private Integer age; private String gender; // 用户特征向量JSON存储或单独表 Column(columnDefinition json) private String featureVector; private LocalDateTime createTime; } // 商品实体 Entity Table(name product) Data public class Product { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String name; private String category; private BigDecimal price; Column(columnDefinition text) private String description; // 商品特征向量用于内容推荐 Column(columnDefinition json) private String featureVector; private Integer salesCount; private LocalDateTime createTime; } // 用户-商品交互记录行为日志 Entity Table(name user_interaction) Data public class UserInteraction { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private Long userId; private Long productId; // 行为类型VIEW, CLICK, PURCHASE, COLLECT private String actionType; private Integer score; // 隐式反馈分数如浏览1购买5 private LocalDateTime actionTime; }2.2.2 协同过滤推荐服务Service Slf4j public class CollaborativeFilteringService { Autowired private UserInteractionRepository interactionRepository; Autowired private ProductRepository productRepository; Autowired private RedisTemplatelt;String, Objectgt; redisTemplate; /** 基于用户的协同过滤UserCF 找到与目标用户兴趣相似的用户群 从相似用户喜欢的商品中推荐目标用户未接触过的商品 */ public Listlt;Productgt; recommendByUserCF(Long userId, int topN) { // 1. 获取目标用户的历史交互商品 Listlt;Longgt; targetUserProductIds interactionRepository.findProductIdsByUserId(userId); // 2. 计算用户相似度这里简化为基于共同交互商品数量的余弦相似度 Maplt;Long, Doublegt; userSimilarityMap new HashMaplt;gt;(); // ... 省略相似度计算具体实现可从Redis缓存中读取预计算的用户相似度矩阵 // 3. 获取最相似的K个用户 Listlt;Longgt; similarUserIds userSimilarityMap.entrySet().stream() .sorted(Map.Entry.lt;Long, Doublegt;comparingByValue().reversed()) .limit(10) .map(Map.Entry::getKey) .collect(Collectors.toList()); // 4. 聚合相似用户喜欢的商品并过滤掉目标用户已交互过的 Maplt;Long, Doublegt; productScoreMap new HashMaplt;gt;(); for (Long similarUserId : similarUserIds) { Listlt;UserInteractiongt; interactions interactionRepository.findByUserId(similarUserId); for (UserInteraction interaction : interactions) { Long productId interaction.getProductId(); if (!targetUserProductIds.contains(productId)) { // 根据行为类型和用户相似度加权计算推荐分数 double score interaction.getScore() * userSimilarityMap.get(similarUserId); productScoreMap.put(productId, productScoreMap.getOrDefault(productId, 0.0) score); } } } // 5. 按分数排序返回TopN商品 return productScoreMap.entrySet().stream() .sorted(Map.Entry.lt;Long, Doublegt;comparingByValue().reversed()) .limit(topN) .map(entry -gt; productRepository.findById(entry.getKey()).orElse(null)) .filter(Objects::nonNull) .collect(Collectors.toList()); } /** 基于物品的协同过滤ItemCF 计算商品之间的相似度 根据用户历史喜欢的商品推荐相似的商品 */ public Listlt;Productgt; recommendByItemCF(Long userId, int topN) { // 从缓存或数据库中获取用户历史交互的正向商品如购买、收藏 Listlt;Longgt; userLikedProductIds interactionRepository.findLikedProductIdsByUserId(userId); // 商品相似度矩阵可离线计算后存入Redis String cacheKey item_similarity_matrix; Maplt;String, Doublegt; similarityMatrix (Maplt;String, Doublegt;) redisTemplate.opsForValue().get(cacheKey); Maplt;Long, Doublegt; candidateProductScore new HashMaplt;gt;(); for (Long likedProductId : userLikedProductIds) { // 获取与该商品最相似的商品列表 Maplt;Long, Doublegt; similarProducts getSimilarProducts(likedProductId, similarityMatrix); for (Map.Entrylt;Long, Doublegt; entry : similarProducts.entrySet()) { Long candidateId entry.getKey(); if (!userLikedProductIds.contains(candidateId)) { candidateProductScore.put(candidateId, candidateProductScore.getOrDefault(candidateId, 0.0) entry.getValue()); } } } // 排序并返回 return candidateProductScore.entrySet().stream() .sorted(Map.Entry.lt;Long, Doublegt;comparingByValue().reversed()) .limit(topN) .map(entry -gt; productRepository.findById(entry.getKey()).orElse(null)) .filter(Objects::nonNull) .collect(Collectors.toList()); } private Maplt;Long, Doublegt; getSimilarProducts(Long productId, Maplt;String, Doublegt; similarityMatrix) { // 实现从相似度矩阵中查询逻辑 return new HashMaplt;gt;(); } }2.2.3 推荐API控制器RestController RequestMapping(/api/recommend) Slf4j public class RecommendController { Autowired private CollaborativeFilteringService cfService; Autowired private ContentBasedService contentBasedService; Autowired private RealTimeRecommendService realTimeService; /** 获取个性化推荐列表混合策略 */ GetMapping(/personalized/{userId}) public ResponseEntitylt;Listlt;ProductDTOgt;gt; getPersonalizedRecommendations( PathVariable Long userId, RequestParam(defaultValue 10) int topN, RequestParam(defaultValue hybrid) String strategy) { Listlt;Productgt; recommendations; switch (strategy) { case user_cf: recommendations cfService.recommendByUserCF(userId, topN); break; case item_cf: recommendations cfService.recommendByItemCF(userId, topN); break; case content: recommendations contentBasedService.recommendByContent(userId, topN); break; case hybrid: // 混合推荐加权融合多种策略的结果 recommendations hybridRecommend(userId, topN); break; default: recommendations cfService.recommendByUserCF(userId, topN); } // 注入实时行为反馈实时层 recommendations realTimeService.adjustByRealTimeBehavior(userId, recommendations); Listlt;ProductDTOgt; dtos recommendations.stream() .map(this::convertToDTO) .collect(Collectors.toList()); return ResponseEntity.ok(dtos); } private Listlt;Productgt; hybridRecommend(Long userId, int topN) { // 实现混合推荐逻辑例如加权分数融合、级联、切换等 return cfService.recommendByUserCF(userId, topN); } private ProductDTO convertToDTO(Product product) { ProductDTO dto new ProductDTO(); dto.setId(product.getId()); dto.setName(product.getName()); dto.setCategory(product.getCategory()); dto.setPrice(product.getPrice()); dto.setDescription(product.getDescription()); dto.setSalesCount(product.getSalesCount()); return dto; } }三、 总结与展望本文介绍了基于Spring Boot的商品推荐系统的技术栈、背景意义以及核心代码实现。一个完整的推荐系统远不止于此还需要考虑特征工程如何构建有效的用户和商品特征。离线训练与在线更新模型如何定期更新以及如何做在线学习。评估与AB测试设计科学的评估指标如CTR、转化率和AB测试框架持续优化推荐效果。冷启动问题针对新用户和新商品设计有效的冷启动策略如热门推荐、基于注册信息的推荐。Spring Boot为推荐系统的工程化落地提供了强大的支持使得算法工程师可以更专注于模型和策略而无需过度纠结于服务框架的复杂性。