首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java全栈 + Python AI:构建跨语言智能推荐系统的完整实践

Java全栈 + Python AI:构建跨语言智能推荐系统的完整实践

原创
作者头像
IT大佬 jzit-top
发布2026-08-29 18:09:59
发布2026-08-29 18:09:59
100
举报

在大型互联网项目中,Java 凭借其卓越的生态与并发性能稳坐后端主力,而 Python 则因 AI 库的丰富性成为算法引擎的首选。如何让两者优雅协作,是许多技术团队面临的现实问题。本文以“商品推荐系统”为例,展示 Java(Spring Boot)提供业务微服务,Python(Flask)提供算法推理服务,并通过 OpenFeign 实现服务间通信,同时前端 Vue 3 负责呈现。全套代码实现了高内聚、低耦合的混合架构。

一、整体架构设计

我们按领域拆分为三个独立服务:

  • Java 商品服务(product-service):管理商品 CRUD、库存、价格。
  • Java 用户服务(user-service):管理用户浏览历史、收藏。
  • Python 推荐引擎(recommend-engine):基于用户历史行为计算协同过滤推荐列表,提供 REST API。

前端 Vue 应用通过网关(或直接)调用商品服务和推荐服务,聚合数据后渲染。服务间通信采用 HTTP + JSON,Python 端使用 Flask 轻量暴露接口,Java 端通过 OpenFeign 声明式调用。

二、Java 后端:业务微服务实现

使用 Spring Boot 3.x + Spring Data JPA + MySQL。以商品服务为例,核心实体与仓库:

代码语言:javascript
复制
// Product.java
@Entity
public class Product {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String category;
    private BigDecimal price;
    private Integer stock;
    // getters/setters
}

// ProductRepository.java
public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findByCategory(String category);
}

商品服务提供 REST 接口:

代码语言:javascript
复制
@RestController
@RequestMapping("/api/products")
public class ProductController {
    @Autowired private ProductRepository repo;
    
    @GetMapping("/{id}")
    public ResponseEntity<Product> getById(@PathVariable Long id) {
        return repo.findById(id).map(ResponseEntity::ok)
                   .orElse(ResponseEntity.notFound().build());
    }
    
    @GetMapping("/batch")
    public List<Product> getBatch(@RequestParam List<Long> ids) {
        return repo.findAllById(ids);
    }
}

用户服务类似,重点记录 UserHistory(userId, productId, timestamp)

三、Python 推荐引擎:协同过滤实时推理

我们采用 基于物品的协同过滤(ItemCF),使用 Pandas 和 Scikit-learn 计算相似度。Flask 提供 /recommend 端点,接收 user_id,返回推荐商品 ID 列表。

代码语言:javascript
复制
# app.py
import pandas as pd
from flask import Flask, request, jsonify
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

app = Flask(__name__)

# 模拟数据:用户-物品评分矩阵(实际可从Java服务拉取或共享数据库)
data = pd.DataFrame({
    'user_id': [1,1,1,2,2,3,3,3],
    'product_id': [101,102,103,101,104,102,103,105],
    'rating': [5,4,3,5,5,4,3,5]
})

# 构建用户-物品矩阵
user_item_matrix = data.pivot(index='user_id', columns='product_id', values='rating').fillna(0)
item_similarity = cosine_similarity(user_item_matrix.T)
item_sim_df = pd.DataFrame(item_similarity, index=user_item_matrix.columns, columns=user_item_matrix.columns)

def recommend(user_id, top_n=5):
    if user_id not in user_item_matrix.index:
        return []  # 新用户冷启动
    user_vector = user_item_matrix.loc[user_id]
    # 找出用户已购商品
    purchased = user_vector[user_vector > 0].index.tolist()
    if not purchased:
        return []
    # 计算每个未购商品的加权得分
    scores = {}
    for item in user_item_matrix.columns:
        if item in purchased:
            continue
        # 计算该物品与用户已购物品的相似度加权评分
        sim_sum = 0
        weight_sum = 0
        for p in purchased:
            sim = item_sim_df.loc[item, p]
            rating = user_vector[p]
            sim_sum += sim * rating
            weight_sum += sim
        if weight_sum > 0:
            scores[item] = sim_sum / weight_sum
    # 排序取top_n
    recommended = sorted(scores.items(), key=lambda x: x[1], reverse=True)[:top_n]
    return [int(item) for item, score in recommended]

@app.route('/recommend', methods=['GET'])
def get_recommend():
    user_id = request.args.get('user_id', type=int)
    if not user_id:
        return jsonify({'error': 'missing user_id'}), 400
    rec_list = recommend(user_id)
    return jsonify({'user_id': user_id, 'recommended_product_ids': rec_list})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001)

此引擎轻量且无状态,可横向扩展。

四、Java 调用 Python 服务(OpenFeign)

在 Java 服务中,我们通过 Spring Cloud OpenFeign 声明式调用推荐引擎。首先定义 Feign 客户端:

代码语言:javascript
复制
@FeignClient(name = "recommend-service", url = "${recommend.service.url:http://localhost:5001}")
public interface RecommendClient {
    @GetMapping("/recommend")
    Map<String, Object> getRecommendations(@RequestParam("user_id") Long userId);
}

然后在推荐聚合服务(或网关)中使用:

代码语言:javascript
复制
@Service
public class RecommendService {
    @Autowired private RecommendClient recommendClient;
    @Autowired private ProductClient productClient; // 调用商品服务
    
    public List<Product> getRecommendProducts(Long userId) {
        Map<String, Object> resp = recommendClient.getRecommendations(userId);
        List<Integer> productIds = (List<Integer>) resp.get("recommended_product_ids");
        if (productIds == null || productIds.isEmpty()) {
            return Collections.emptyList();
        }
        // 将 Integer 转为 Long
        List<Long> ids = productIds.stream().map(Long::valueOf).collect(Collectors.toList());
        return productClient.getBatch(ids); // 批量查询商品详情
    }
}

为了保证高可用,我们为 Feign 配置 重试和降级(使用 Resilience4j):

代码语言:javascript
复制
@Bean
public Retryer retryer() {
    return new Retryer.Default(100, 1000, 3); // 间隔100ms,最多3次
}

// 降级工厂
@Bean
public RecommendClient fallback() {
    return userId -> {
        log.warn("推荐服务不可用,返回默认推荐");
        return Map.of("recommended_product_ids", List.of(101, 102, 103));
    };
}

五、前端 Vue 3 整合展示

前端使用 Vue 3 + Axios 调用 Java 网关,统一入口。核心组件如下:

代码语言:javascript
复制
<template>
  <div>
    <h2>为您推荐</h2>
    <el-row :gutter="20">
      <el-col :span="6" v-for="p in products" :key="p.id">
        <el-card :body-style="{ padding: '10px' }">
          <img :src="p.image" style="width:100%"/>
          <div>{{ p.name }}</div>
          <div>¥{{ p.price }}</div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'

const products = ref([])
const userId = ref(1) // 实际从登录态获取

onMounted(async () => {
  const resp = await axios.get(`/api/recommend?userId=${userId.value}`)
  products.value = resp.data
})
</script>

网关层聚合 Java 服务和 Python 服务的调用,前端只需一次请求,获得完整商品数据。

六、部署与性能优化关键点

  1. 共享数据源:Python 引擎的数据可定期从 Java 服务的 MySQL 同步,避免重复存储,可通过 Redis 缓存用户特征向量。
  2. 异步化:对于推荐结果时效性要求不高,可采用 异步 @Async 调用 Python 服务,并用 Spring Cache 缓存结果(TTL=10分钟)。
  3. 序列化优化:使用 Protobuf 或 MessagePack 替代 JSON,降低跨语言传输带宽。
  4. 容器化:编写 Dockerfile 分别打包 Java 服务和 Python 服务,用 docker-compose 统一编排,便于扩展。

七、总结与思考

本文成功搭建了一个 Java 全栈 + Python AI 的混合推荐系统,核心价值在于:

  • 各取所长:Java 负责健壮的业务逻辑和事务管理,Python 负责灵活的算法迭代。
  • 标准通信:RESTful + JSON 消除了语言壁垒,团队可独立开发部署。
  • 容错设计:重试、降级、缓存保证了系统弹性。

这套模式广泛适用于推荐、图像识别、自然语言处理等 AI 附属服务。未来可演进为 gRPC 通信以获得更高性能,或引入服务网格(Istio)进行流量治理。跨语言不再是障碍,而是架构组合的优势。掌握此范式,开发者便可在全栈与 AI 之间自由穿梭。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 在大型互联网项目中,Java 凭借其卓越的生态与并发性能稳坐后端主力,而 Python 则因 AI 库的丰富性成为算法引擎的首选。如何让两者优雅协作,是许多技术团队面临的现实问题。本文以“商品推荐系统”为例,展示 Java(Spring Boot)提供业务微服务,Python(Flask)提供算法推理服务,并通过 OpenFeign 实现服务间通信,同时前端 Vue 3 负责呈现。全套代码实现了高内聚、低耦合的混合架构。
    • 一、整体架构设计
    • 二、Java 后端:业务微服务实现
    • 三、Python 推荐引擎:协同过滤实时推理
    • 四、Java 调用 Python 服务(OpenFeign)
    • 五、前端 Vue 3 整合展示
    • 六、部署与性能优化关键点
    • 七、总结与思考
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档