1. 项目概述黔醉酒业白酒销售系统技术架构解析黔醉酒业白酒销售系统是一个典型的Java Web全栈项目采用当前主流的技术栈组合SpringBoot2Vue3MyBatis-PlusMySQL8.0。这个系统最核心的价值在于实现了基于协同过滤算法的白酒个性化推荐功能这在酒类垂直电商领域具有创新意义。我在实际开发中发现酒类电商与传统电商的最大区别在于用户决策链路更长、产品专业度要求更高。系统通过协同过滤算法分析用户的浏览、购买行为建立用户-商品关联矩阵能够有效提升高单价白酒的转化率。整个技术栈的选择也体现了现代Java Web开发的典型特征后端采用SpringBoot2快速构建微服务架构前端使用Vue3实现响应式界面ORM层通过MyBatis-Plus简化数据库操作MySQL8.0则提供了完善的JSON支持和窗口函数等高级特性。提示选择SpringBoot2而非SpringBoot3主要是考虑到企业现有系统的兼容性需求SpringBoot2的社区支持更成熟稳定2. 核心技术点深度解析2.1 协同过滤算法实现系统采用基于用户的协同过滤(UserCF)算法核心代码位于RecommendService.java中。算法实现主要分为三个步骤用户行为数据收集通过埋点收集用户浏览、收藏、购买等行为// 用户行为权重定义 public enum BehaviorType { BROWSE(1), COLLECT(3), PURCHASE(5); // ... }相似度矩阵计算使用改进的余弦相似度算法加入时间衰减因子public double similarity(User a, User b) { // 时间衰减因子λ0.5 double timeDecay Math.pow(0.5, (now - lastTime)/86400); return cosineSimilarity(a.getBehaviorVector(), b.getBehaviorVector()) * timeDecay; }推荐结果生成取相似度最高的K个邻居用户的行为进行加权推荐在实际应用中我们发现白酒品类具有明显的场景化特征如商务宴请、婚庆、收藏等因此在基础算法上增加了场景维度使推荐结果更符合用户真实需求。2.2 SpringBoot2后端架构设计后端采用典型的三层架构但有几个值得注意的设计亮点多数据源配置主库用于交易从库用于报表和分析Configuration MapperScan(basePackages com.qianzui.mapper.primary, sqlSessionTemplateRef primarySqlSessionTemplate) public class PrimaryDataSourceConfig { // 主数据源配置 }分布式锁实现使用Redisson解决秒杀场景下的超卖问题public boolean seckill(Long productId) { RLock lock redissonClient.getLock(seckill: productId); try { if(lock.tryLock(1, 10, TimeUnit.SECONDS)) { // 扣减库存逻辑 } } finally { lock.unlock(); } }接口幂等设计通过token机制防止重复提交PostMapping(/order/create) public Result createOrder(RequestBody OrderDTO dto, RequestHeader(Idempotent-Token) String token) { if(!redisTemplate.opsForValue().setIfAbsent(token, 1, 5, TimeUnit.MINUTES)) { return Result.fail(请勿重复提交); } // 创建订单逻辑 }2.3 Vue3前端工程化实践前端采用Vue3TypeScript技术栈主要技术特点包括组件化开发基于Composition API重构业务组件// 使用setup语法糖 script setup langts const recommendList refProduct[]([]) const loading ref(false) const loadRecommend async (userId: string) { loading.value true recommendList.value await getRecommendations(userId) loading.value false } /script状态管理Pinia替代Vuex实现更简洁的状态管理export const useUserStore defineStore(user, { state: () ({ token: localStorage.getItem(token) || , userInfo: null as UserInfo | null }), actions: { async login(params: LoginParams) { const res await api.login(params) this.token res.token this.userInfo res.userInfo } } })性能优化基于v-memo的列表渲染优化template div v-foritem in list v-memo[item.id] !-- 复杂列表项内容 -- /div /template3. 数据库设计与优化3.1 MySQL8.0特性应用系统充分利用了MySQL8.0的新特性窗口函数实现销售排行榜SELECT product_id, sales_volume, RANK() OVER(ORDER BY sales_volume DESC) as rank FROM product_sales WHERE category 白酒JSON字段存储商品扩展属性CREATE TABLE products ( id BIGINT PRIMARY KEY, base_info JSON, spec_info JSON, INDEX idx_category ((CAST(base_info-$.category AS CHAR(20)))) );公用表表达式(CTE)优化复杂查询WITH user_behavior AS ( SELECT user_id, product_id, behavior_type, behavior_time FROM user_behaviors WHERE behavior_time DATE_SUB(NOW(), INTERVAL 30 DAY) ) SELECT product_id, COUNT(*) as hot_score FROM user_behavior GROUP BY product_id ORDER BY hot_score DESC LIMIT 10;3.2 分库分表策略针对订单表的大数据量问题我们采用了按月分表的策略动态表名拦截器实现public class OrderTableInterceptor implements InnerInterceptor { Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { // 根据时间参数动态修改表名 if(parameter instanceof OrderQuery ((OrderQuery)parameter).getMonth() ! null) { String newTable orders_ ((OrderQuery)parameter).getMonth(); String newSql boundSql.getSql().replace(orders, newTable); resetSql(ms, boundSql, newSql); } } }历史订单归档策略Scheduled(cron 0 0 3 * * ?) public void archiveOrders() { LocalDate archiveDate LocalDate.now().minusMonths(6); String sourceTable orders_ archiveDate.format(DateTimeFormatter.ofPattern(yyyyMM)); String archiveTable orders_archive_ archiveDate.format(DateTimeFormatter.ofPattern(yyyyMM)); jdbcTemplate.execute(CREATE TABLE IF NOT EXISTS archiveTable LIKE sourceTable); jdbcTemplate.execute(INSERT INTO archiveTable SELECT * FROM sourceTable); jdbcTemplate.execute(DROP TABLE sourceTable); }4. 系统部署与性能调优4.1 容器化部署方案系统采用Docker Compose进行容器编排version: 3 services: app: image: openjdk:11-jre ports: - 8080:8080 volumes: - ./app.jar:/app.jar command: java -jar /app.jar depends_on: - mysql - redis mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: qianzui ports: - 3306:3306 volumes: - ./mysql/data:/var/lib/mysql - ./mysql/conf:/etc/mysql/conf.d redis: image: redis:6 ports: - 6379:6379 volumes: - ./redis/data:/data4.2 JVM参数调优针对白酒促销期间的高并发场景我们对JVM参数进行了特别优化-XX:UseG1GC -XX:MaxGCPauseMillis200 -XX:InitiatingHeapOccupancyPercent45 -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m -Xms2g -Xmx2g -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/opt/heapdump.hprof4.3 缓存策略设计采用多级缓存架构提升系统响应速度本地缓存(Caffeine) Redis分布式缓存Cacheable(value products, key #id, cacheManager caffeineCacheManager) public Product getProductById(Long id) { // 数据库查询 } Cacheable(value products, key #id, cacheManager redisCacheManager) public Product getProductDetail(Long id) { // 数据库查询 }热点数据预加载Scheduled(fixedRate 3600000) public void preloadHotProducts() { ListLong hotIds productMapper.selectHotProductIds(); hotIds.forEach(id - { productService.getProductById(id); productService.getProductDetail(id); }); }5. 典型问题排查实录5.1 MyBatis-Plus分页查询性能问题现象当查询结果集超过10万条时分页查询变慢解决方案使用基于游标的分页替代传统LIMIT分页public IPageUser selectUsersByCursor(Long lastId, int size) { return lambdaQuery() .gt(lastId ! null, User::getId, lastId) .orderByAsc(User::getId) .page(new Page(1, size, false)); }添加覆盖索引优化查询ALTER TABLE users ADD INDEX idx_status_create_time (status, create_time, id);5.2 Vue3组件重复渲染问题现象推荐列表组件在数据更新时出现闪烁解决方案使用v-memo优化渲染性能template div v-foritem in list v-memo[item.id, item.isRecommended] ProductCard :productitem / /div /template合理使用watchEffect替代多个watchwatchEffect(() { if (userStore.isLoggedIn) { loadRecommendations(userStore.userId) } })5.3 MySQL8.0连接池耗尽问题现象高峰时段出现Too many connections错误解决方案优化连接池配置spring: datasource: hikari: maximum-pool-size: 50 idle-timeout: 60000 max-lifetime: 1800000 connection-timeout: 30000启用连接泄漏检测Bean public HikariDataSource dataSource() { HikariConfig config new HikariConfig(); config.setLeakDetectionThreshold(30000); return new HikariDataSource(config); }6. 项目文档要点解析系统提供的文档包含以下几个关键部分架构设计文档系统上下文图部署架构图微服务划分方案数据库设计文档ER图表结构说明索引设计规范API接口文档Swagger UI集成接口签名算法错误码规范运维手册健康检查端点日志收集方案监控指标说明在白酒推荐算法部分文档特别强调了AB测试框架的使用方法包括如何配置实验分组如何埋点收集效果数据如何进行统计学显著性检验注意实际部署时需要根据服务器配置调整JVM参数和连接池大小文档中的配置值仅供参考
阅读完成 · 觉得有帮助?