麦瓣健康麦瓣健康
首页
  • APP产品开发方案
  • 商业调查报告
  • 后端技术架构
  • Docker Compose部署指南
  • 技师端-功能模块与微服务对应关系
  • 数据库设计
  • 分布式事务一致性
  • 日志管理与配置
  • Netdata监控系统
  • 系统总览
  • 文档导航
  • 代码审计智能体
  • 测试生成智能体
  • 运维诊断智能体
  • APP测试智能体
  • API自动化测试多智能体协作系统
  • 项目规划
  • 开发工作手册
  • 开发周期管理
  • 任务看板总览
  • Week 3任务看板
  • Week 3周例会
  • Week 4任务看板
  • Week 5任务看板
  • Week 6任务看板
  • APP测试设备采购清单
  • 用户端APP
  • 用户端APP功能脑图
  • 技师端APP
  • 技师端APP功能脑图
  • 后台管理
  • 大数据屏幕
  • 技师端-账户系统需求明细
原型图(Demo)
GitHub
首页
  • APP产品开发方案
  • 商业调查报告
  • 后端技术架构
  • Docker Compose部署指南
  • 技师端-功能模块与微服务对应关系
  • 数据库设计
  • 分布式事务一致性
  • 日志管理与配置
  • Netdata监控系统
  • 系统总览
  • 文档导航
  • 代码审计智能体
  • 测试生成智能体
  • 运维诊断智能体
  • APP测试智能体
  • API自动化测试多智能体协作系统
  • 项目规划
  • 开发工作手册
  • 开发周期管理
  • 任务看板总览
  • Week 3任务看板
  • Week 3周例会
  • Week 4任务看板
  • Week 5任务看板
  • Week 6任务看板
  • APP测试设备采购清单
  • 用户端APP
  • 用户端APP功能脑图
  • 技师端APP
  • 技师端APP功能脑图
  • 后台管理
  • 大数据屏幕
  • 技师端-账户系统需求明细
原型图(Demo)
GitHub
  • 技术架构

    • 麦瓣健康后端技术架构文档
    • /Docker部署指南.html
    • 技师端功能模块与微服务对应关系
    • 数据库设计文档
    • 麦瓣健康 - 微服务分布式事务一致性设计方案
    • 日志管理与配置说明
    • Netdata 监控系统技术文档

麦瓣健康后端技术架构文档

项目名称: ⻨瓣健康 - 后端微服务架构
技术栈: Spring Boot 3.2 + Spring Cloud 2023 & Alibaba
文档版本: v3.2(章节编号修复版)
最后更新: 2025-11-07

原文档引用: 本文档从 麦瓣健康-APP产品开发方案.md 中的后端技术架构部分独立而来,包含完整的技术选型、架构设计、微服务实现指南等详细内容。

⚠️ 架构风险提示: 本文档基于架构复盘分析进行了优化,重点关注:分布式事务优化、缓存策略完善、降级容灾方案、MVP最小化实施。建议开发前仔细阅读"第二十一章:架构风险与优化建议"。


一、技术架构概览

1.1 架构设计

本项目后端架构采用微服务架构设计模式,结合康护到家业务特点进行定制化开发。

1.2 核心技术栈

微服务框架

  • 语言: Java 17
  • 框架: Spring Boot 3.2 + Spring Cloud 2023 & Alibaba
  • API网关: Spring Cloud Gateway (含限流、熔断、灰度发布)
  • 服务注册与发现: Nacos 2.x
  • 配置中心: Nacos Config
  • 认证授权: Sa-Token (轻量级,替代Spring Security OAuth2)
  • API文档: Knife4j (Swagger增强版)
  • 服务监控: Spring Boot Admin + Prometheus + Grafana
  • 链路追踪: SkyWalking (生产环境必选)
  • 限流熔断: Sentinel (流量防护)

数据存储

  • 关系数据库: MySQL 8.0 (主从架构,读写分离)
  • 数据库连接池: HikariCP (Spring Boot 3默认)
  • ORM框架: MyBatis
    • 重要约束:必须使用 XML Mapper 配置,禁用 @Select/@Insert/@Update/@Delete 注解
    • MyBatis Generator 配置 targetRuntime="MyBatis3" 生成 XML 配置
    • 所有 SQL 语句统一在 XML 文件中编写,便于维护和审查
    • 复杂查询使用动态 SQL(<if>, <choose>, <foreach> 等标签)
  • 分页插件: PageHelper
  • 缓存: Redis 7.x (⚠️ 生产环境必须集群部署:主从+哨兵或Cluster模式)
    • 用途:缓存、分布式锁、GEO位置、消息队列
  • 搜索引擎: Elasticsearch 7.17.3 (技师搜索、商品搜索、日志分析)
  • NoSQL: MongoDB 5.0 (护理日志、聊天记录)
  • 对象存储: 阿里云OSS / MinIO (私有云)

消息与通信

  • 消息队列: RabbitMQ 3.10+
  • WebSocket: Spring WebSocket
  • 短信服务: 阿里云短信
  • 邮件服务: Spring Mail

分布式解决方案

  • 分布式事务: 本地消息表 + MQ(✅ 推荐方案,详见分布式事务一致性设计方案)
    • 推荐场景:订单支付、积分发放、通知推送等大部分场景(80%+)
    • 备选方案:Seata AT模式(⚠️ 仅用于资金账户操作:扣款、退款)
    • 性能对比:本地消息表(80ms,800 TPS)vs Seata AT(500ms,100 TPS)
  • 分布式锁: Redis (护理师抢单、秒杀库存扣减)
  • 任务调度: XXL-Job(分布式任务调度,支持故障转移)

DevOps工具

  • 容器化: Docker
  • 容器编排: Kubernetes (生产环境)
  • 容器管理: Portainer
  • CI/CD: Jenkins
  • 日志收集: ELK (Elasticsearch + Logstash + Kibana)

第三方集成

  • 地图服务: 高德地图API (导航、距离计算、位置追踪)
  • 支付接口: 微信支付 + 支付宝 (含分账、企业付款)
  • 实名认证: 阿里云实人认证
  • 人脸识别: 腾讯云/阿里云
  • 物流查询: 快递100 / 菜鸟物流API
  • AI能力: 通义千问 / OpenAI (体检报告分析、智能推荐)
  • 敏感词过滤: 阿里云内容安全 / 腾讯云天御

开发工具

  • 代码简化: Lombok
  • 代码生成: MyBatisGenerator (MBG)

1.3 基础设施服务端口总览

本项目使用Docker Compose部署基础设施服务,以下为各服务的端口配置:

服务名称容器名称版本端口映射说明默认账号
MySQLmaiban-mysql8.03306:3306关系数据库root / Maiban@2025#Mysql!
Redismaiban-redis7-alpine6379:6379缓存/分布式锁无密码
Nacosmaiban-nacos2.2.38848:8848
9848:9848
服务注册/配置中心
gRPC通信端口
nacos / nacos
RabbitMQmaiban-rabbitmq3.125672:5672
15672:15672
消息队列
管理界面
admin / admin123
Elasticsearchmaiban-es7.17.39200:9200
9300:9300
搜索引擎
节点通信端口
无认证
MongoDBmaiban-mongo5.027017:27017NoSQL数据库admin / admin123
MinIOmaiban-miniolatest9000:9000
9001:9001
对象存储API
管理控制台
minioadmin / minioadmin123
Netdatamaiban-netdatastable19999:19999系统监控无认证

基础设施管理界面访问地址:

服务访问地址账号密码用途
Nacos控制台http://localhost:8848/nacosnacos / nacos服务注册与配置管理
RabbitMQ管理界面http://localhost:15672admin / admin123消息队列监控
MinIO控制台http://localhost:9001minioadmin / minioadmin123对象存储管理
Netdata监控http://localhost:19999无需认证系统性能监控
Elasticsearchhttp://localhost:9200无需认证搜索引擎API

1.4 服务文档与管理界面访问地址

📚 API文档访问地址(Knife4j/Swagger):

✅ = 已验证可访问 | ⚠️ = 需要配置 | 测试时间:2025-10-24

服务名称文档访问地址OpenAPI地址状态说明
网关聚合文档(推荐)http://localhost:8201/doc.htmlhttp://localhost:8201/v3/api-docs✅所有微服务文档聚合
认证服务http://localhost:8401/doc.htmlhttp://localhost:8401/v3/api-docs✅登录注册、Token管理
用户服务http://localhost:8080/doc.htmlhttp://localhost:8080/v3/api-docs✅用户信息、家庭成员
技师服务http://localhost:8082/doc.htmlhttp://localhost:8082/v3/api-docs✅技师列表、接单管理
订单服务http://localhost:8083/doc.htmlhttp://localhost:8083/v3/api-docs✅订单创建、状态查询
支付服务http://localhost:8084/doc.htmlhttp://localhost:8084/v3/api-docs✅支付、退款、提现
IM消息服务http://localhost:8085/doc.htmlhttp://localhost:8085/v3/api-docs✅即时通讯、推送
健康管理服务http://localhost:8087/doc.htmlhttp://localhost:8087/v3/api-docs✅健康档案、护理日志
搜索服务http://localhost:8089/doc.htmlhttp://localhost:8089/v3/api-docs✅技师搜索、商品搜索
营销服务http://localhost:8090/doc.htmlhttp://localhost:8090/v3/api-docs✅优惠券、积分、会员
商城服务http://localhost:8091/doc.htmlhttp://localhost:8091/v3/api-docs✅商品、购物车、订单
后台管理服务http://localhost:8180/doc.htmlhttp://localhost:8180/v3/api-docs⚠️需检查Knife4j配置

🔍 监控中心访问地址:

✅ = 已验证可访问 | 测试时间:2025-10-24

监控服务访问地址账号密码状态说明
Spring Boot Adminhttp://localhost:8101无需认证(开发环境)✅微服务统一监控面板
Nacos控制台http://localhost:8848/nacosnacos / nacos✅服务注册与配置管理
RabbitMQ管理界面http://localhost:15672admin / admin123✅消息队列监控管理
MinIO控制台http://localhost:9001minioadmin / minioadmin123✅对象存储管理
Netdata监控http://localhost:19999无需认证✅系统性能实时监控
Elasticsearchhttp://localhost:9200无需认证✅搜索引擎API

🏥 健康检查地址(Spring Boot Actuator):

服务健康检查地址指标监控地址
API网关http://localhost:8201/actuator/healthhttp://localhost:8201/actuator/metrics
监控中心http://localhost:8101/actuator/healthhttp://localhost:8101/actuator/metrics
认证服务http://localhost:8401/actuator/healthhttp://localhost:8401/actuator/metrics
用户服务http://localhost:8080/actuator/healthhttp://localhost:8080/actuator/metrics
技师服务http://localhost:8082/actuator/healthhttp://localhost:8082/actuator/metrics
订单服务http://localhost:8083/actuator/healthhttp://localhost:8083/actuator/metrics
支付服务http://localhost:8084/actuator/healthhttp://localhost:8084/actuator/metrics
IM消息服务http://localhost:8085/actuator/healthhttp://localhost:8085/actuator/metrics
健康管理服务http://localhost:8087/actuator/healthhttp://localhost:8087/actuator/metrics
搜索服务http://localhost:8089/actuator/healthhttp://localhost:8089/actuator/metrics
营销服务http://localhost:8090/actuator/healthhttp://localhost:8090/actuator/metrics
商城服务http://localhost:8091/actuator/healthhttp://localhost:8091/actuator/metrics
后台管理服务http://localhost:8180/actuator/healthhttp://localhost:8180/actuator/metrics

📝 Nacos详细功能入口:

功能模块访问地址说明
服务列表http://localhost:8848/nacos/#/serviceManagement查看所有注册的微服务
配置管理http://localhost:8848/nacos/#/configurationManagement管理配置文件
命名空间http://localhost:8848/nacos/#/namespace环境隔离管理
集群管理http://localhost:8848/nacos/#/clusterManagement查看集群节点状态

📊 RabbitMQ详细功能入口:

功能模块访问地址说明
队列监控http://localhost:15672/#/queues查看所有队列状态
交换机管理http://localhost:15672/#/exchanges管理交换机
连接监控http://localhost:15672/#/connections查看客户端连接
通道监控http://localhost:15672/#/channels查看通道状态

⚠️ 使用建议:

  1. 开发调试:优先使用网关聚合文档(http://localhost:8201/doc.html),可以在一个页面查看所有微服务API
  2. 服务监控:使用Spring Boot Admin(http://localhost:8101)统一监控所有微服务状态
  3. 配置管理:通过Nacos控制台(http://localhost:8848/nacos)统一管理所有配置
  4. 系统监控:使用Netdata(http://localhost:19999)实时监控系统资源使用情况

⚠️ 安全提示:

  • 生产环境务必修改所有默认密码
  • 生产环境应关闭或限制Actuator端点访问
  • 建议通过VPN或内网访问管理界面
  • API文档在生产环境应设置访问权限或关闭

二、微服务架构设计

2.1 服务拆分原则与边界

拆分原则:

  1. 业务领域拆分:按DDD领域模型拆分(用户域、订单域、支付域等)
  2. 数据独立性:每个服务拥有独立数据库,避免跨库事务
  3. 变化频率隔离:高频变化功能独立服务(营销活动、运营配置)
  4. 性能隔离:高并发场景独立部署(IM消息、秒杀活动)

边界划分示例:

  • 护理日志:元数据(订单ID、技师ID)→ 订单服务;详细内容(体征、照片)→ 健康管理服务
  • 优惠券:券模板、库存 → 营销服务;订单使用记录 → 订单服务
  • 技师位置:实时位置(Redis GEO)→ 订单服务;历史轨迹 → 健康管理服务

2.2 微服务模块详解

麦瓣健康平台共包含以下模块:

核心基础模块

模块职责端口关键功能
maiban-common公共模块-通用工具类、统一返回封装CommonResult、分页封装CommonPage、自定义注解
maiban-auth认证授权8401Sa-Token集成、JWT Token生成验证、手机号验证码登录、微信授权
maiban-gatewayAPI网关8201Spring Cloud Gateway、统一路由、限流鉴权、CORS配置、Knife4j文档聚合
maiban-monitor服务监控8101Spring Boot Admin Server、健康状态监控、JVM监控、日志查看

业务微服务模块(10个服务,支撑225个功能点)

模块名服务名称端口核心职责关键功能模块关键技术
maiban-user用户服务8080用户体系管理• 注册登录(手机号/微信/实名认证)
• 家庭成员管理
• 地址管理
• 个人信息、收藏、浏览历史
• 老带新/邀请好友
MyBatis、Redis缓存、阿里云实名认证
maiban-nurse技师服务8082技师体系管理• 技师注册、资质审核
• 在线状态、接单管理
• 技师列表/详情/筛选/搜索
• AI智能推荐算法
• 评分/等级体系
• 师徒关系管理
Redis分布式锁、Elasticsearch搜索、AI推荐引擎
maiban-order订单服务8083订单全流程管理• 订单创建、支付、状态流转
• 预约管理(立即/未来/长期)
• 实时位置追踪
• 服务延时、取消、退款
• 打卡记录、里程计算
• 套餐卡核销
状态机、RabbitMQ延时队列、Redis位置缓存、高德地图API
maiban-payment支付财务服务8084支付结算体系• 微信/支付宝/余额支付
• 回调处理、退款流水
• 佣金计算、分账、提现
• 里程补贴、奖励发放
• 账单汇总、电子发票
第三方支付SDK、Seata分布式事务、定时任务
maiban-health-service健康管理服务8087健康数据管理• 健康档案(病史/用药/过敏)
• 护理日志、体征数据
• 体检报告上传/AI分析
• 健康计划、数据对比
• 物联网设备集成、数据同步
• 健康报告生成(PDF)
AES加密、MongoDB存储、阿里云OSS、AI分析引擎
maiban-marketing营销服务8090营销运营体系• 优惠券(领取/使用/分享/叠加)
• 积分系统、会员体系、成长值
• 红包系统(现金/随机/口令/红包雨)
• 签到打卡、任务中心
• 运营活动(秒杀/拼团/满减)
• 新手引导、新人礼包
Redis计数、定时任务、规则引擎
maiban-imIM消息服务8085通讯推送体系• 即时通讯IM(文字/图片/语音/位置)
• 敏感词过滤、客服介入
• 极光推送/模板消息
• 通知中心(订单/系统/活动/健康)
• WebSocket实时通信
Spring WebSocket、RabbitMQ、极光推送、敏感词库
maiban-mall商城服务8091电商业务体系• 商品管理、分类
• 购物车、商城订单
• 库存管理、物流跟踪
• 退货退款
• 商品评价
• 护理套餐管理
Redis库存、物流API
maiban-search搜索服务8089搜索引擎体系• 技师搜索
• 商品搜索
• 搜索建议
• 热门搜索
• 搜索结果排序
Elasticsearch搜索引擎
maiban-admin运营管理服务8180后台管理体系• 用户/技师审核
• 订单管理、财务统计
• 内容审核(社区/评价)
• 数据报表、业绩分析
• RBAC权限管理
• 客服系统、投诉处理
RBAC权限、ECharts报表、Elasticsearch日志分析

三、服务边界与依赖约束

3.1 微服务依赖管理原则

核心原则:业务微服务间零直接依赖

为了保证微服务架构的独立性和可维护性,必须严格控制微服务间的依赖关系,避免出现复杂的网状依赖和循环依赖。

3.2 依赖隔离约束

禁止事项:

  • ❌ 业务微服务 A 直接依赖业务微服务 B 的 jar 包
  • ❌ 业务微服务 A 直接引用业务微服务 B 的 Repository、Service、Entity 等类
  • ❌ 通过依赖传递绕过依赖限制(如 A 依赖 common,B 依赖 common,A 间接依赖 B)

允许操作:

  • ✅ 通过 HTTP/gRPC API 调用对方服务接口
  • ✅ 通过消息队列(RabbitMQ)进行异步通信
  • ✅ 通过事件总线进行事件发布与订阅
  • ✅ 依赖 maiban-common 等公共基础库
  • ✅ 依赖数据库、缓存、MQ 等基础设施组件

3.3 公共能力沉淀策略

公共模块层级划分:

maiban-common(基础公共模块)
├── 通用工具类(日期、字符串、加密等)
├── 统一返回封装(CommonResult、CommonPage)
├── 自定义注解(@Log、@DataScope等)
├── 通用异常类(BusinessException、SystemException)
├── 通用 DTO(分页请求、基础响应等)
└── 公共常量(状态枚举、错误码等)

各业务微服务
├── maiban-auth(认证授权服务)
├── maiban-user(用户服务)
├── maiban-nurse(技师服务)
├── maiban-order(订单服务)
├── maiban-payment(支付服务)
├── maiban-health-service(健康管理服务)
├── maiban-marketing(营销服务)
├── maiban-im(IM消息服务)
├── maiban-mall(商城服务)
├── maiban-search(搜索服务)
└── maiban-admin(运营管理服务)

依赖方向:

业务微服务 → maiban-common(单向依赖)
业务微服务 ↔ 业务微服务(禁止直接依赖)

3.4 服务间通信方式

同步调用(HTTP/gRPC):

场景通信方式说明示例
查询类接口HTTP RESTful实时查询对方服务数据订单服务调用用户服务查询用户信息
事务性操作HTTP RESTful + 幂等性需要保证操作原子性支付服务调用订单服务更新订单状态
强一致性要求gRPC高性能、低延迟网关转发高并发请求
批量查询HTTP + 批量接口减少网络开销营销服务批量查询用户积分

异步调用(消息队列):

场景消息队列说明示例
跨服务业务事件RabbitMQ解耦服务间同步调用订单完成 → 营销服务发放积分
延时任务RabbitMQ + 死信队列处理超时取消场景订单支付超时自动取消
通知推送RabbitMQ异步通知,不阻塞主流程订单状态变更 → IM服务推送通知
数据同步RabbitMQ最终一致性数据同步用户信息变更 → 各服务缓存更新

事件驱动架构:

// 订单服务发布订单完成事件
@Component
public class OrderEventPublisher {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void publishOrderCompleted(Order order) {
        OrderCompletedEvent event = new OrderCompletedEvent(order);
        rabbitTemplate.convertAndSend("order.exchange", "order.completed", event);
    }
}

// 营销服务订阅订单完成事件
@Component
public class MarketingEventConsumer {

    @RabbitListener(queues = "order.completed.queue")
    public void handleOrderCompleted(OrderCompletedEvent event) {
        // 发放积分
        marketingService.creditPoints(event.getUserId(), event.getOrderAmount());
    }
}

3.5 依赖检测与验证机制

本地开发阶段:

1. Maven 依赖树检查

# 在每个微服务目录下执行
mvn dependency:tree > dependency-tree.log

# 检查是否存在业务微服务依赖
grep -E "maiban-(user|nurse|order|payment|health|marketing|im|mall|search|admin)" dependency-tree.log

2. IDE 插件检查

  • 安装 Maven Helper 插件
  • 实时检查依赖冲突和循环依赖
  • 可视化依赖关系图

3. ArchUnit 架构测试

@ArchTest
static final ArchRule service_should_not_depend_on_other_services = noClasses()
    .that()
    .resideInAPackage("com.maiban.health.user..")
    .should()
    .dependOnClassesThat()
    .resideInAPackage("com.maiban.health.nurse..")
    .orShould()
    .dependOnClassesThat()
    .resideInAPackage("com.maiban.health.order..")
    .check();

CI/CD 流水线检查:

1. 依赖白名单校验

# .github/workflows/dependency-check.yml
name: Dependency Check
on: [pull_request]

jobs:
  dependency-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Check business service dependencies
        run: |
          # 提取项目依赖
          mvn dependency:tree -DoutputFile=dependencies.txt

          # 校验是否存在跨业务服务依赖
          if grep -E "com\.maiban\.health\.(user|nurse|order|payment|health|marketing|im|mall|search|admin):" dependencies.txt; then
            echo "❌ 检测到跨业务服务依赖!"
            exit 1
          fi

2. 构建产物扫描

# 扫描 jar 包内容,确保不包含其他服务的类
jar -tf target/maiban-user-*.jar | grep -E "com\.maiban\.health\.(nurse|order|payment)" && {
    echo "❌ jar 包中包含其他服务代码!"
    exit 1
}

3. 静态代码分析

<!-- pom.xml 配置 -->
<plugin>
    <groupId>com.github.ferstl</groupId>
    <artifactId>depgraph-maven-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <graphFormat>text</graphFormat>
    </configuration>
</plugin>

# 生成依赖关系图,审查是否存在异常依赖
mvn depgraph:graph

3.6 依赖约束违规处理

检测到违规依赖的处理流程:

  1. 开发阶段

    • 代码 Review 阶段拒绝合并代码
    • IDE 提示警告和错误
    • 本地构建失败
  2. CI/CD 阶段

    • 构建流水线中断
    • 生成详细依赖报告
    • 通知相关开发人员
  3. 生产环境

    • 拒绝部署违规服务
    • 要求立即整改
    • 回滚到上一个合规版本

常见违规场景与解决方案:

违规场景错误示例正确方案
直接依赖对方 ServiceuserService.getUserInfo()通过 Feign Client 或 REST API 调用
共享数据库表同时访问 user 表各服务独立数据库,通过 API 同步数据
循环依赖A 依赖 B,B 依赖 A通过消息事件解耦,移除直接依赖
工具类复制各服务复制相同工具类抽离到 maiban-common 基础库

3.7 最佳实践建议

1. 接口设计规范

// ✅ 推荐:清晰的接口定义
@FeignClient(name = "maiban-user")
public interface UserServiceClient {
    @GetMapping("/api/v1/user/{userId}")
    CommonResult<UserInfoDTO> getUserInfo(@PathVariable Long userId);
}

// ❌ 禁止:直接依赖 Service 类
@Autowired
private UserService userService; // 禁止!

2. 数据一致性处理

// ✅ 推荐:最终一致性
@RabbitListener(queues = "user.updated.queue")
public void handleUserUpdated(UserUpdatedEvent event) {
    // 异步更新本地缓存
    cacheService.updateUserInfo(event.getUserId(), event.getUserInfo());
}

// ❌ 禁止:同步调用并共享数据库
// userRepository.updateUser(userInfo) // 禁止!

3. 配置管理

# 各服务独立配置文件
maiban-user/src/main/resources/application.yml:
  spring:
    application:
      name: maiban-user  # 唯一标识,与 Nacos 服务名一致

# 禁止共享配置类
// ❌ @Configuration + @Bean 跨服务共享
// ✅ 各服务独立配置

四、Nacos配置中心

4.1 部署与配置

Nacos Server 部署:

  • 下载Nacos 2.2.3版本,解压后执行 sh startup.sh -m standalone 单机启动
  • 访问控制台 http://localhost:8848/nacos (默认账号密码: nacos/nacos)
  • 生产环境建议集群部署(3个节点以上),使用MySQL存储配置

命名空间设计:

  • dev: 开发环境
  • test: 测试环境
  • prod: 生产环境

4.2 微服务配置结构

本地配置(application.yml):

  • 服务名称: spring.application.name
  • Nacos地址: spring.cloud.nacos.discovery.server-addr
  • 环境激活: spring.profiles.active

Nacos配置中心:

  • 数据库连接配置
  • Redis配置
  • 第三方服务密钥(使用环境变量)

配置自动刷新:

  • 启用 refresh-enabled: true
  • 使用 @RefreshScope 注解动态刷新Bean

4.3 关键配置项

数据库配置:

  • MySQL驱动: com.mysql.cj.jdbc.Driver
  • 连接池: HikariCP (Spring Boot 3默认)
  • MyBatis映射: mybatis.mapper-locations

Redis配置:

  • 连接配置: spring.redis.host / port
  • 密码: spring.redis.password
  • 超时设置: spring.redis.timeout

RabbitMQ配置:

  • 主机: spring.rabbitmq.host
  • 端口: spring.rabbitmq.port
  • 虚拟主机: spring.rabbitmq.virtual-host

Sa-Token配置:

  • Token名称: sa-token.token-name
  • 超时时间: 30天 (2592000秒)
  • JWT密钥: 使用环境变量 ${JWT_SECRET}

日志配置:

  • 按包名设置日志级别
  • 开发环境: logging.level.com.health=debug
  • 生产环境: logging.level.com.health=info

五、Spring Cloud Gateway

5.1 路由配置策略

自动服务发现:

  • 启用 discovery.locator.enabled: true,自动从Nacos发现服务
  • 服务ID小写转换: lower-case-service-id: true

核心路由规则(10个业务服务 + 1个认证服务):

前端路径目标服务说明版本优先级
/api/v1/auth/**maiban-auth认证授权服务(登录、注册、Token刷新)v11
/api/v1/user/**maiban-user用户服务(用户信息、家庭成员、地址管理)v12
/api/v1/nurse/**maiban-nurse技师服务(技师列表、详情、接单管理)v13
/api/v1/order/**maiban-order订单服务(订单创建、状态流转、预约管理)v14
/api/v1/payment/**maiban-payment支付财务服务(支付、退款、分账、提现)v15
/api/v1/health/**maiban-health-service健康管理服务(健康档案、护理日志、体检报告)v16
/api/v1/marketing/**maiban-marketing营销服务(优惠券、积分、会员、红包)v17
/api/v1/im/**maiban-imIM消息服务(即时通讯、推送通知)v18
/api/v1/mall/**maiban-mall商城服务(商品、购物车、商城订单)v19
/api/v1/search/**maiban-search搜索服务(技师搜索、商品搜索)v110
/api/v1/admin/**maiban-admin运营管理服务(后台管理、数据报表)v111

路由规则说明:

  • 所有路由统一使用 /api/v1/ 前缀,便于后续版本迭代(v2、v3...)
  • 路由转发时去掉 /api/v1 前缀,保留业务路径
  • 优先级按照业务重要性排序,数字越小优先级越高
  • 认证服务优先级最高,保证登录注册等核心功能优先匹配

版本管理策略:

  • v1: 当前稳定版本,兼容所有客户端
  • v2: 未来版本,支持新功能,逐步迁移
  • 旧版本保留至少6个月,给客户端充足的升级时间
  • 重大变更需要版本升级,小修复可在当前版本热更新

限流配置:

  • 使用Redis实现分布式限流
  • replenishRate: 10 (每秒补充10个令牌)
  • burstCapacity: 20 (桶容量20个令牌)

5.2 完整Gateway配置示例

application.yml 配置文件 (maiban-gateway/src/main/resources/application.yml):

spring:
  application:
    name: maiban-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      # 服务发现配置
      discovery:
        locator:
          enabled: true  # 启用服务发现
          lower-case-service-id: true  # 服务名小写

      # 路由规则配置
      routes:
        # 1. 认证授权服务
        - id: maiban-auth
          uri: lb://maiban-auth
          predicates:
            - Path=/api/v1/auth/**
          filters:
            - StripPrefix=2  # 去掉/api/v1前缀
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 20
                redis-rate-limiter.burstCapacity: 40

        # 2. 用户服务
        - id: maiban-user
          uri: lb://maiban-user
          predicates:
            - Path=/api/v1/user/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

        # 3. 技师服务
        - id: maiban-nurse
          uri: lb://maiban-nurse
          predicates:
            - Path=/api/v1/nurse/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

        # 4. 订单服务
        - id: maiban-order
          uri: lb://maiban-order
          predicates:
            - Path=/api/v1/order/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 15
                redis-rate-limiter.burstCapacity: 30

        # 5. 支付财务服务
        - id: maiban-payment
          uri: lb://maiban-payment
          predicates:
            - Path=/api/v1/payment/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

        # 6. 健康管理服务
        - id: maiban-health-service
          uri: lb://maiban-health-service
          predicates:
            - Path=/api/v1/health/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

        # 7. 营销服务
        - id: maiban-marketing
          uri: lb://maiban-marketing
          predicates:
            - Path=/api/v1/marketing/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 15
                redis-rate-limiter.burstCapacity: 30

        # 8. IM消息服务
        - id: maiban-im
          uri: lb://maiban-im
          predicates:
            - Path=/api/v1/im/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 20
                redis-rate-limiter.burstCapacity: 40

        # 9. 商城服务
        - id: maiban-mall
          uri: lb://maiban-mall
          predicates:
            - Path=/api/v1/mall/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

        # 10. 搜索服务
        - id: maiban-search
          uri: lb://maiban-search
          predicates:
            - Path=/api/v1/search/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 15
                redis-rate-limiter.burstCapacity: 30

        # 11. 运营管理服务
        - id: maiban-admin
          uri: lb://maiban-admin
          predicates:
            - Path=/api/v1/admin/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 5
                redis-rate-limiter.burstCapacity: 10

      # 全局CORS配置
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOriginPatterns: "*"  # 生产环境改为具体域名
            allowedMethods:
              - GET
              - POST
              - PUT
              - DELETE
              - OPTIONS
            allowedHeaders: "*"
            allowCredentials: true
            maxAge: 3600

# Redis配置(限流使用)
  redis:
    host: localhost
    port: 6379
    password: ${REDIS_PASSWORD:}
    timeout: 3000ms

server:
  port: 8201

# 日志配置
logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    com.maiban.health.gateway: INFO

路由配置说明:

配置项说明示例
id路由唯一标识maiban-user
uri目标服务地址(lb=负载均衡)lb://maiban-user
predicates路由匹配规则Path=/api/v1/user/**
filters过滤器(转发前处理)StripPrefix=2
replenishRate限流速率(每秒令牌数)10
burstCapacity令牌桶容量20

5.3 全局过滤器

跨域CORS配置:

  • 允许所有来源 (生产环境需指定具体域名)
  • 允许方法: GET、POST、PUT、DELETE、OPTIONS
  • 允许携带凭证: allowCredentials: true

认证鉴权过滤器:

  • 从请求头提取Authorization token
  • 白名单路径: /login、/register、/captcha (直接放行)
  • 非白名单路径: 验证Token有效性,失败返回401
  • 过滤器优先级: -100 (最高优先级)

日志过滤器:

  • 记录请求路径、方法、IP、耗时
  • 异常请求详细日志记录
  • 慢请求告警(>2秒)

六、Sa-Token认证授权

6.1 登录认证流程

手机号验证码登录:

  1. 验证验证码正确性(Redis存储,5分钟有效期)
  2. 根据手机号查询或创建用户
  3. 调用 StpUtil.login(userId) 完成登录
  4. 获取Token: StpUtil.getTokenValue()
  5. 返回用户信息+Token给客户端

微信授权登录:

  1. 使用微信code换取openid
  2. 根据openid查询或创建用户(绑定手机号)
  3. Sa-Token登录生成Token
  4. 返回用户信息

Token管理:

  • Token有效期: 30天
  • 刷新机制: StpUtil.renewTimeout(2592000)
  • 登出: StpUtil.logout() 清除Token

6.2 权限控制方案

基于角色的权限控制:

  • @SaCheckRole("admin"): 仅管理员可访问
  • @SaCheckRole({"admin", "operator"}, mode = SaMode.OR): 管理员或运营均可访问
  • 角色存储在Redis,支持动态更新

自定义权限验证:

  • 检查当前登录用户ID: StpUtil.getLoginIdAsLong()
  • 业务逻辑验证: 只能查看本人或下属数据
  • 抛出 BusinessException 进行权限拦截

权限缓存策略:

  • 角色权限缓存10分钟
  • 权限变更实时刷新缓存
  • 登出清除所有权限缓存

七、OpenFeign服务间通信

7.1 Feign Client设计

接口定义约定:

  • @FeignClient(name = "服务名", fallbackFactory = 降级工厂类)
  • 服务名必须与Nacos注册的服务名一致
  • 接口方法与被调用服务的Controller方法签名一致

核心接口示例:

  • 用户服务Client: 查询用户信息、批量查询、扣减余额
  • 护理师服务Client: 查询护理师、更新在线状态、评分计算
  • 支付服务Client: 创建支付单、查询支付状态、退款

降级策略:

  • 实现 FallbackFactory 接口
  • 服务不可用时返回友好提示: "XXX服务暂时不可用"
  • 记录失败日志,便于排查问题
  • 避免降级中执行复杂逻辑

6.2 服务调用场景

订单创建场景:

  1. 调用用户服务查询用户信息(验证用户状态)
  2. 调用护理师服务查询护理师信息(验证可接单状态)
  3. 本地创建订单记录
  4. 调用消息服务发送订单通知

订单支付场景:

  1. 调用支付服务创建支付流水
  2. 调用用户服务扣减余额(余额支付)
  3. 更新订单状态为已支付
  4. 调用消息服务通知护理师

调用优化:

  • 批量接口减少网络开销(批量查询用户、护理师)
  • 合理设置超时时间(默认1秒,复杂查询3秒)
  • 启用请求压缩减少带宽
  • 使用连接池复用连接

八、RabbitMQ异步消息

8.1 延时队列实现订单超时取消

队列设计:

  • 延时交换机: order.delay.exchange
  • 延时队列: order.delay.queue (设置死信交换机)
  • 取消交换机: order.cancel.exchange
  • 取消队列: order.cancel.queue

工作流程:

  1. 创建订单后发送延时消息到延时队列,过期时间15分钟
  2. 消息过期后自动转发到死信交换机
  3. 死信交换机路由到取消队列
  4. 消费者监听取消队列,检查订单状态
  5. 如果仍是"待支付",自动取消订单

配置要点:

  • 延时队列设置: x-dead-letter-exchange 指定死信交换机
  • 消息过期时间: setExpiration("900000") (15分钟)
  • 消费者幂等性: 检查订单状态防止重复取消

7.2 消息可靠性保证

生产者确认:

  • 启用 publisher-confirms: true
  • 发送失败重试3次
  • 记录失败消息到数据库

消费者ACK:

  • 手动ACK模式
  • 消费成功后确认
  • 消费失败重新入队(最多3次)

死信队列:

  • 消费失败超过3次进入死信队列
  • 人工介入处理异常消息

九、服务依赖关系与核心场景

9.1 服务依赖关系图

用户端/技师端/管理后台
         ↓
    API网关 (maiban-gateway)
         ↓
    ┌────────────────────────────────┐
    │      业务微服务层(10个)         │
    ├────────────────────────────────┤
    │ 用户服务 ← → 技师服务             │
    │    ↓           ↓                │
    │ 订单服务 ← → 支付财务服务         │
    │    ↓           ↓                │
    │ 健康管理 ← → 营销服务             │
    │    ↓           ↓                │
    │ IM消息  ← → 商城服务              │
    │             ↓                  │
    │         运营管理服务              │
    └────────────────────────────────┘
         ↓
    基础设施层
    (Nacos/Redis/MySQL/MongoDB/RabbitMQ/Elasticsearch)

8.2 核心业务场景调用链

场景1: 用户下单预约护理服务

1. 用户服务: 验证用户身份和实名认证状态
2. 技师服务: 查询可用技师列表(支持AI推荐)
3. 订单服务: 创建订单、计算价格(含优惠)
4. 营销服务: 计算优惠券/积分/会员折扣
5. 支付财务服务: 创建支付单、调用微信/支付宝
6. 订单服务: 更新订单状态为"已支付"
7. IM消息服务: 推送订单通知给技师
8. 技师服务: 技师接单、更新状态
9. IM消息服务: 推送接单成功通知给用户

场景2: 技师完成服务提交护理日志

1. 订单服务: 验证订单状态、打卡记录
2. 健康管理服务: 保存护理日志、体征数据
3. 对象存储(OSS): 上传护理照片
4. 订单服务: 更新订单状态为"已完成"
5. 支付财务服务: 触发分账、佣金计算
6. 技师服务: 更新技师完单数、评分
7. 营销服务: 发放完单奖励、积分
8. IM消息服务: 推送服务完成通知给用户

场景3: 用户购买会员享受权益

1. 用户服务: 验证用户身份
2. 营销服务: 创建会员订单(99元/年)
3. 支付财务服务: 完成支付
4. 营销服务: 开通会员权益、发放专属优惠券
5. 健康管理服务: 激活AI体测权益(每月1次)
6. 商城服务: 更新商品显示价格(会员折扣)
7. IM消息服务: 推送会员开通成功通知

场景4: 技师通过老带新邀请徒弟

1. 技师服务: 生成专属邀请码
2. 用户服务: 新技师注册(通过邀请码)
3. 技师服务: 建立师徒关系
4. 营销服务: 发放邀请奖励(师傅50元、徒弟阶段性奖励)
5. 支付财务服务: 奖励金入账
6. IM消息服务: 推送奖励到账通知
7. (后续)订单服务: 徒弟完单触发师傅提成(2%)
8. 支付财务服务: 提成计算、每日结算

场景5: 运营创建限时秒杀活动

1. 运营管理服务: 创建秒杀活动
2. 商城服务: 配置秒杀商品、库存
3. Redis: 预热商品库存到缓存
4. IM消息服务: 推送活动通知
5. (用户抢购)商城服务: Redis扣减库存
6. 订单服务: 创建秒杀订单
7. 支付财务服务: 完成支付
8. 商城服务: 异步扣减数据库库存

8.3 服务拆分原则

原则说明应用示例
业务领域按DDD领域拆分用户域、技师域、订单域独立
数据一致性强一致性数据放同一服务订单状态+支付状态在订单服务
变化频率高频变化功能独立服务营销活动独立,避免影响核心服务
团队组织按团队边界拆分前端团队→用户服务,运营团队→营销服务
性能隔离高并发场景独立部署IM消息服务独立,避免消息风暴影响订单

8.4 服务通信方式

场景通信方式说明
同步查询OpenFeign查询用户信息、技师详情
异步通知RabbitMQ订单状态变更、支付回调
实时推送WebSocket订单实时更新、IM消息
定时任务XXL-Job订单超时取消、每日结算
事件驱动RabbitMQ订单完成→触发分账+奖励+通知

十、数据一致性方案

📘 完整设计方案: 麦瓣健康-微服务分布式事务一致性设计方案

本章节为概要说明,详细的生产级实现方案(含完整代码、SQL、监控配置)请参考上述文档。

9.1 分布式事务使用原则

⚠️ 重要原则:优先使用最终一致性,避免过度使用分布式事务

性能对比:

方案响应时间吞吐量一致性推荐场景
本地事务50ms1000 TPS强一致单服务操作
本地消息表80ms800 TPS最终一致✅ 大部分场景(80%+)
Saga模式100ms500 TPS最终一致✅ 需要补偿的流程
Seata AT500ms100 TPS强一致⚠️ 仅资金操作(<5%)

9.2 推荐方案:本地消息表 + MQ

📘 详细设计文档: 麦瓣健康-微服务分布式事务一致性设计方案

该文档包含完整的生产级实现方案,包括:

  • 系统架构设计:微服务全景架构、分布式事务流程、数据流与状态机
  • 数据库设计:本地消息表、持久幂等表、死信队列表(含完整SQL)
  • 生产级代码实现:RabbitMQ配置(Publisher Confirms)、并发扫描(SKIP LOCKED)、手动ACK消费
  • 幂等性保证:持久去重表、业务唯一索引、外部调用幂等键、状态机、Redis短期锁
  • 失败重试策略:发布端重试(抖动算法)、消费端重试(延迟队列+DLX)、DLQ处理
  • 监控告警与运维:核心指标(Prometheus)、告警规则、运维Runbook、链路追踪、Grafana面板

适用场景:订单支付、积分发放、通知推送等大部分场景

实现流程:

1. 本地事务:更新订单状态 + 插入消息表(事务表)
2. 定时任务:扫描消息表,发送MQ消息(Publisher Confirms保证可靠)
3. 消费者:幂等处理业务(积分发放、通知)+ 手动ACK
4. 消费成功:更新消息状态为已处理 + 持久去重表防重
5. 失败重试:最多3次(指数退避+抖动),超过则进入DLQ人工介入

优势:

  • ✅ 性能好:接近本地事务性能(响应时间80ms,吞吐量800 TPS)
  • ✅ 可靠性高:消息不丢失(Publisher Confirms + 手动ACK)
  • ✅ 解耦:服务间松耦合
  • ✅ 可运维:完整监控告警体系,支持故障快速定位

9.3 Seata分布式事务(谨慎使用)

⚠️ 仅用于以下场景:

  1. 余额扣减:用户服务扣减余额 + 订单服务创建订单
  2. 退款操作:支付服务退款 + 用户服务增加余额

使用示例(简化):

@GlobalTransactional(name = "refund-order-tx", rollbackFor = Exception.class)
public void refundOrder(Long orderId) {
    // 1. 更新订单状态
    orderMapper.updateStatus(orderId, REFUNDED);
    // 2. 创建退款记录
    paymentService.createRefund(orderId);
    // 3. 增加用户余额(跨服务调用)
    userService.addBalance(userId, amount);
}

性能优化要点:

  • 控制事务粒度,避免长事务(<3秒)
  • 非关键流程异步化(如发送通知)
  • 监控事务耗时,超时告警

9.4 TCC模式(高级场景)

适用场景:需要精确控制资源的场景(库存扣减、秒杀)

三阶段说明:

  • Try:冻结资源(库存预扣,写入冻结表)
  • Confirm:确认扣减(实际扣除库存)
  • Cancel:取消回滚(释放冻结库存)

实现要点:幂等性处理 + 唯一流水号防重

9.5 数据对账机制

每日对账任务:

1. 对比订单表 vs 支付流水表
2. 识别差异订单:
   - 订单已支付但无支付流水 → 订单异常
   - 支付流水存在但订单未更新 → 补偿更新
3. 生成对账报告,差异订单人工介入

关键指标监控:

  • 对账差异率:< 0.1%
  • 补偿成功率:> 99%

十一、Docker + Kubernetes部署

10.1 Docker镜像构建

Dockerfile最佳实践:

  • 基础镜像: openjdk:17-slim (精简版)
  • 多阶段构建减小镜像体积
  • 使用 .dockerignore 排除无关文件
  • 健康检查: HEALTHCHECK CMD curl -f http://localhost:{PORT}/actuator/health

镜像分层优化:

  • 依赖层(pom.xml依赖)单独缓存
  • 业务代码层独立,提高构建速度
  • 镜像大小控制在200MB以内

10.2 Kubernetes部署

资源配置:

  • Deployment: 每个微服务独立部署,副本数2-3
  • Service: ClusterIP类型,内部服务间通信
  • Ingress: 暴露API网关,统一入口
  • ConfigMap: 存储配置文件
  • Secret: 存储敏感信息(数据库密码、密钥)

资源限制:

  • Request: CPU 500m、内存512Mi
  • Limit: CPU 2000m、内存2Gi
  • 根据实际负载动态调整

滚动更新:

  • strategy: RollingUpdate
  • maxSurge: 1 (最多额外启动1个Pod)
  • maxUnavailable: 0 (保证服务不中断)

健康检查:

  • Liveness Probe: 检查服务是否存活
  • Readiness Probe: 检查服务是否就绪接收流量
  • 探测路径: /actuator/health

十二、监控与日志

12.1 Spring Boot Admin服务监控

监控指标:

  • JVM内存使用率、GC次数
  • 线程池状态(活跃线程数、队列长度)
  • HTTP请求量、响应时间
  • 数据库连接池状态
  • 缓存命中率

告警配置:

  • 内存使用率>80%告警
  • 响应时间>2秒告警
  • 错误率>5%告警
  • 发送通知: 邮件、钉钉、企业微信

11.2 ELK日志收集

日志采集:

  • Logstash收集各微服务日志
  • 日志格式统一JSON格式
  • 包含: 时间戳、服务名、日志级别、TraceId、消息

日志存储:

  • Elasticsearch存储,按天创建索引
  • 保留周期: 最近30天
  • 冷数据归档到OSS

日志查询:

  • Kibana可视化查询
  • 按TraceId追踪完整请求链路
  • 错误日志聚合分析

11.3 SkyWalking链路追踪

追踪范围:

  • HTTP请求链路
  • RPC调用(OpenFeign)
  • 数据库查询
  • Redis操作
  • 消息队列

性能分析:

  • 慢请求分析(>2秒)
  • SQL慢查询定位
  • 服务依赖拓扑图
  • 接口性能趋势

十三、数据库设计

详细数据库设计文档: 请参见 数据库设计文档-完整版.md

该文档包含完整的数据库架构设计、12张核心表详细结构、订单状态机、索引优化策略、数据备份恢复、数据安全与合规等详细内容。

13.1 数据库技术栈

技术组件版本/方案用途说明
数据库MySQL 8.0主数据库,支持JSON字段类型
连接池HikariCPSpring Boot 3默认连接池
ORM框架MyBatis对象关系映射,XML配置
缓存层Redis 7.x热点数据缓存
NoSQLMongoDB 5.0护理日志非结构化数据
主从架构MySQL Master-Slave读写分离,提升性能

十四、第三方服务集成

14.1 微信支付配置

配置步骤:

  1. 登录微信商户平台获取商户号
  2. 下载商户私钥证书apiclient_key.pem
  3. 设置APIv3密钥(32字节随机字符串)
  4. 获取证书序列号
  5. 配置支付回调域名白名单

环境变量配置:

  • WX_PAY_MERCHANT_ID: 商户号
  • WX_PAY_API_V3_KEY: APIv3密钥
  • WX_PAY_CERT_SERIAL_NO: 证书序列号

13.2 支付宝支付配置

配置步骤:

  1. 登录支付宝开放平台创建应用
  2. 生成RSA2密钥对
  3. 上传应用公钥,获取支付宝公钥
  4. 配置授权回调地址和支付回调地址
  5. 提交应用审核上线

环境变量配置:

  • ALIPAY_APP_ID: 应用ID
  • ALIPAY_PRIVATE_KEY: 应用私钥
  • ALIPAY_PUBLIC_KEY: 支付宝公钥

13.3 高德地图配置

服务端Web API:

  • 申请Web服务API Key
  • 配置IP白名单
  • 使用: 地理编码、逆地理编码、距离计算、路径规划

环境变量配置:

  • AMAP_API_KEY: 高德地图API Key

13.4 极光推送配置

Flutter端配置:

  • 申请Android和iOS应用
  • 下载配置文件
  • 集成JPush SDK

环境变量配置:

  • JPUSH_APP_KEY: 极光推送AppKey
  • JPUSH_MASTER_SECRET: MasterSecret

13.5 阿里云OSS配置

配置步骤:

  1. 登录阿里云OSS控制台创建Bucket
  2. 设置Bucket访问权限(推荐私有读写,通过签名URL访问)
  3. 创建RAM子账号,授予OSS读写权限
  4. 配置跨域规则CORS允许前端直传
  5. 设置生命周期规则自动删除过期文件

环境变量配置:

  • ALIYUN_OSS_ENDPOINT: 节点域名
  • ALIYUN_OSS_BUCKET_NAME: Bucket名称
  • ALIYUN_OSS_ACCESS_KEY_ID: AccessKey ID
  • ALIYUN_OSS_ACCESS_KEY_SECRET: AccessKey Secret

13.6 阿里云短信服务配置

配置步骤:

  1. 登录阿里云短信服务控制台
  2. 申请短信签名(需企业资质,2-3个工作日审核)
  3. 申请短信模板(不同场景需不同模板)
  4. 创建RAM子账号,授予短信发送权限
  5. 购买短信套餐包

环境变量配置:

  • ALIYUN_SMS_ACCESS_KEY_ID: AccessKey ID
  • ALIYUN_SMS_ACCESS_KEY_SECRET: AccessKey Secret
  • ALIYUN_SMS_SIGN_NAME: 短信签名
  • ALIYUN_SMS_TEMPLATE_CODE: 短信模板CODE

13.7 实名认证配置(阿里云)

配置步骤:

  1. 登录阿里云实人认证控制台
  2. 开通实人认证服务
  3. 选择认证方案(人脸识别+身份证OCR)
  4. 配置回调地址
  5. 购买认证次数包(按次计费)

环境变量配置:

  • ALIYUN_VERIFY_ACCESS_KEY_ID: AccessKey ID
  • ALIYUN_VERIFY_ACCESS_KEY_SECRET: AccessKey Secret

13.8 第三方服务成本预估

服务计费方式预估成本(月)
微信支付0.6%手续费按交易额计算
支付宝0.6%手续费按交易额计算
高德地图API按调用次数500-1000元
极光推送按推送条数300-500元
阿里云OSS按存储+流量200-300元
阿里云短信0.045元/条500-800元
实名认证0.3-1元/次300-500元
合计-2000-3600元

成本优化建议:

  1. 高德地图API使用缓存,减少重复调用
  2. OSS配置生命周期,自动清理过期文件
  3. 短信验证码添加图形验证码前置,防止恶意刷短信
  4. 推送服务区分重要通知和普通通知,降低推送频率

十五、编码标准

15.1 代码标准

命名约定:

  • 包名: com.maiban.health.{模块名}
  • 类名: 大驼峰命名法
  • 方法名: 小驼峰命名法
  • 常量: 全大写下划线分隔

注释要求:

  • 类级别注释: 说明类的职责
  • 方法级别注释: 说明参数、返回值、异常
  • 关键业务逻辑注释

14.1.1 MyBatis 编码规范(重要)

强制要求:必须使用 XML Mapper 配置

为什么使用 XML 配置而非注解:

对比维度XML 配置注解方式推荐
复杂 SQL清晰易读,支持格式化字符串拼接,难维护✅ XML
动态 SQL完整标签支持受限,需要拼接✅ XML
代码审查SQL 变更一目了然混在代码中,易遗漏✅ XML
性能优化ResultMap 灵活映射配置受限✅ XML
SQL 管理集中管理,便于 DBA 审查分散在各个类中✅ XML
接口简洁性接口只有方法声明接口被注解污染✅ XML

MyBatis Generator 配置要求:

<!-- generatorConfig.xml 配置示例 -->
<generatorConfiguration>
    <context id="MaibanContext" targetRuntime="MyBatis3">
        <!-- ✅ 正确:使用 MyBatis3 生成 XML 配置 -->
        <!-- ❌ 错误:不要使用 MyBatis3Simple 或 MyBatis3DynamicSql -->
        
        <!-- 生成 Model 类 -->
        <javaModelGenerator targetPackage="com.maiban.health.nurse.mbg.model" 
                           targetProject="src/main/java"/>
        
        <!-- 生成 XML Mapper 文件 -->
        <sqlMapGenerator targetPackage="com.maiban.health.nurse.mbg.mapper" 
                        targetProject="src/main/resources"/>
        
        <!-- 生成 Mapper 接口(仅方法声明,无注解) -->
        <javaClientGenerator type="XMLMAPPER" 
                            targetPackage="com.maiban.health.nurse.mbg.mapper"
                            targetProject="src/main/java"/>
    </context>
</generatorConfiguration>

Mapper 接口规范(禁止使用注解):

// ✅ 正确示例:接口简洁,无注解
public interface NurseMapper {
    /**
     * 根据 ID 查询技师信息
     */
    Nurse selectByPrimaryKey(Long id);
    
    /**
     * 根据条件查询技师列表
     */
    List<Nurse> selectByExample(NurseExample example);
    
    /**
     * 插入技师信息
     */
    int insert(Nurse record);
    
    /**
     * 更新技师信息
     */
    int updateByPrimaryKey(Nurse record);
}

// ❌ 错误示例:禁止使用注解
public interface NurseMapper {
    @Select("SELECT * FROM nurses WHERE id = #{id}")  // ❌ 禁止
    Nurse selectByPrimaryKey(Long id);
    
    @Insert("INSERT INTO nurses ...")  // ❌ 禁止
    int insert(Nurse record);
}

XML Mapper 规范:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.maiban.health.nurse.mbg.mapper.NurseMapper">
    
    <!-- ResultMap 定义 -->
    <resultMap id="BaseResultMap" type="com.maiban.health.nurse.mbg.model.Nurse">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <result column="name" property="name" jdbcType="VARCHAR"/>
        <result column="phone" property="phone" jdbcType="VARCHAR"/>
        <!-- 更多字段映射... -->
    </resultMap>
    
    <!-- 基础查询 SQL -->
    <sql id="Base_Column_List">
        id, name, phone, gender, status, created_at, updated_at
    </sql>
    
    <!-- 简单查询 -->
    <select id="selectByPrimaryKey" parameterType="java.lang.Long" 
            resultMap="BaseResultMap">
        SELECT <include refid="Base_Column_List"/>
        FROM nurses
        WHERE id = #{id,jdbcType=BIGINT}
    </select>
    
    <!-- 动态 SQL 示例 -->
    <select id="selectByExample" parameterType="com.maiban.health.nurse.mbg.model.NurseExample"
            resultMap="BaseResultMap">
        SELECT <include refid="Base_Column_List"/>
        FROM nurses
        <where>
            <if test="name != null and name != ''">
                AND name LIKE CONCAT('%', #{name}, '%')
            </if>
            <if test="status != null">
                AND status = #{status}
            </if>
            <if test="cityId != null">
                AND city_id = #{cityId}
            </if>
        </where>
        ORDER BY created_at DESC
    </select>
    
    <!-- 批量插入示例 -->
    <insert id="batchInsert" parameterType="java.util.List">
        INSERT INTO nurses (name, phone, gender, status)
        VALUES
        <foreach collection="list" item="item" separator=",">
            (#{item.name}, #{item.phone}, #{item.gender}, #{item.status})
        </foreach>
    </insert>
    
    <!-- 复杂联表查询示例 -->
    <select id="selectNurseWithCertificates" resultMap="NurseWithCertificatesMap">
        SELECT 
            n.id, n.name, n.phone,
            c.id as cert_id, c.cert_name, c.cert_no
        FROM nurses n
        LEFT JOIN nurse_certificates c ON n.id = c.nurse_id
        WHERE n.id = #{nurseId}
    </select>
    
    <resultMap id="NurseWithCertificatesMap" type="com.maiban.health.nurse.dto.NurseWithCertificatesDTO">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="phone" property="phone"/>
        <collection property="certificates" ofType="com.maiban.health.nurse.mbg.model.NurseCertificate">
            <id column="cert_id" property="id"/>
            <result column="cert_name" property="certName"/>
            <result column="cert_no" property="certNo"/>
        </collection>
    </resultMap>
</mapper>

动态 SQL 常用标签:

标签用途示例
<if>条件判断<if test="name != null">AND name = #{name}</if>
<choose>多条件分支<choose><when><otherwise>
<where>智能 WHERE 子句自动去除多余的 AND/OR
<set>智能 SET 子句UPDATE 时自动处理逗号
<foreach>循环遍历批量插入、IN 查询
<trim>去除前后缀灵活处理 SQL 片段
<sql>SQL 片段复用定义公共字段列表

包路径规范:

项目结构:
src/main/java/com/maiban/health/{service}/
  ├── mbg/
  │   ├── model/              # MyBatis Generator 生成的实体类
  │   │   ├── Nurse.java
  │   │   └── NurseExample.java
  │   └── mapper/             # MyBatis Generator 生成的 Mapper 接口
  │       └── NurseMapper.java
  ├── mapper/                 # 自定义 Mapper 接口(扩展)
  │   └── NurseExtMapper.java
  └── service/
      └── NurseService.java

src/main/resources/com/maiban/health/{service}/mbg/mapper/
  ├── NurseMapper.xml         # MyBatis Generator 生成的 XML
  └── NurseExtMapper.xml      # 自定义 Mapper 的 XML

代码检查清单:

  • [ ] ✅ Mapper 接口中无任何注解(@Select/@Insert/@Update/@Delete)
  • [ ] ✅ 所有 SQL 语句都在 XML 文件中
  • [ ] ✅ 复杂查询使用了动态 SQL 标签
  • [ ] ✅ ResultMap 定义清晰,字段映射完整
  • [ ] ✅ 使用 <sql> 标签复用公共 SQL 片段
  • [ ] ✅ XML 文件格式化规范,缩进一致
  • [ ] ✅ SQL 语句可读性好,关键字大写

14.2 接口标准

统一返回格式:

返回成功:

  • code: 200
  • message: "成功"
  • data: 业务数据

返回失败:

  • code: 错误码
  • message: 错误描述
  • data: null

分页返回格式:

  • pageNum: 当前页
  • pageSize: 每页数量
  • total: 总记录数
  • list: 数据列表

14.3 异常处理

异常分类:

  • BusinessException: 业务异常(可预期)
  • SystemException: 系统异常(不可预期)

全局异常处理:

  • 使用 @RestControllerAdvice 统一处理
  • 记录错误日志
  • 返回友好错误提示

14.4 日志标准

日志级别:

  • ERROR: 严重错误,需立即处理
  • WARN: 警告信息,需关注
  • INFO: 一般信息,业务流程关键节点
  • DEBUG: 调试信息,仅开发环境

日志内容:

  • 包含: 时间戳、日志级别、类名、方法名、消息
  • 敏感信息脱敏(手机号、身份证号)

十六、上线检查清单

16.1 代码检查

  • [ ] 代码标准检查(阿里巴巴Java编码标准)
  • [ ] 代码review完成
  • [ ] 单元测试覆盖率>80%
  • [ ] 集成测试通过
  • [ ] 性能测试通过

15.2 配置检查

  • [ ] 生产环境配置正确
  • [ ] 敏感信息使用环境变量
  • [ ] 数据库连接池配置合理
  • [ ] Redis连接池配置合理
  • [ ] 日志级别配置为INFO

15.3 部署检查

  • [ ] Docker镜像构建成功
  • [ ] Kubernetes配置正确
  • [ ] 健康检查配置正确
  • [ ] 资源限制配置合理
  • [ ] 滚动更新策略配置

15.4 监控检查

  • [ ] Spring Boot Admin监控正常
  • [ ] ELK日志收集正常
  • [ ] SkyWalking链路追踪正常
  • [ ] 告警配置正确
  • [ ] 告警通知渠道正常

十七、Redis缓存策略详解

17.1 缓存更新策略

Cache-Aside Pattern(推荐):

操作执行顺序说明
读操作1. 查缓存 → 2. 缓存Miss → 3. 查数据库 → 4. 写缓存标准读取流程
写操作1. 更新数据库 → 2. 删除缓存⚠️ 先更新DB,再删缓存

为什么删除缓存而不是更新?

  • 避免并发更新导致脏数据
  • 减少缓存写入次数(读多写少场景)
  • 下次读取时自动回填最新数据

16.2 缓存雪崩/击穿/穿透防护

三大问题对比:

问题原因影响解决方案
雪崩大量key同时过期DB瞬间压力激增过期时间加随机值(30±5分钟)
击穿热点key过期瞬间大量请求打到DB互斥锁(SETNX)或永不过期
穿透查询不存在的数据缓存无效,每次都查DB布隆过滤器 + 缓存空值

实现方案:

1. 防穿透:布隆过滤器 + 缓存空值

流程:
1. 布隆过滤器判断用户是否存在
2. 不存在 → 直接返回null(不查DB)
3. 存在 → 查缓存 → 缓存Miss → 查DB
4. DB也没有 → 缓存空对象5分钟

2. 防击穿:分布式锁

热点key(如热门技师):
1. 缓存Miss时,尝试获取分布式锁
2. 获取成功 → 查DB → 回填缓存 → 释放锁
3. 获取失败 → 等待100ms后重试(最多3次)

3. 防雪崩:过期时间随机化

// 基础过期时间30分钟,加上0-5分钟随机值
int expireTime = 1800 + RandomUtils.nextInt(0, 300);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);

16.3 缓存分层策略

层级技术场景TTL命中率
L1 本地缓存Caffeine技师资质、服务项目配置10分钟95%
L2 Redis缓存Redis用户信息、技师详情30分钟85%
L3 数据库MySQL持久化数据--

本地缓存 + Redis两级缓存:

  • 减少Redis网络开销(L1命中率95%)
  • 适合读多写少的配置数据
  • 注意:更新时需清理两级缓存

16.4 Redis高可用方案

开发环境:单机模式

成本:1台服务器
可用性:99%
适用:开发、测试环境

生产环境方案一:主从 + 哨兵(推荐初期)

架构:1主2从 + 3哨兵
成本:3台服务器
可用性:99.9%
故障恢复:自动切换(<30秒)
适用:日活<10万

生产环境方案二:Redis Cluster(推荐中后期)

架构:6节点(3主3从)
成本:6台服务器
可用性:99.99%
性能:数据分片,QPS提升3倍
适用:日活>10万或数据量>100GB

16.5 缓存监控指标

指标健康值告警阈值处理方式
缓存命中率>80%<70%优化缓存策略
内存使用率<70%>85%扩容或清理
慢查询<10ms>50ms优化数据结构
连接数<500>800检查连接泄漏

十八、降级容灾方案

18.1 服务降级策略

限流降级(Sentinel):

服务限流阈值降级策略恢复时间
订单服务1000 QPS返回"系统繁忙"实时监控
支付服务500 QPS排队等待自动恢复
IM消息2000 QPS延迟推送1分钟
营销服务300 QPS关闭活动入口5分钟

实现方案(注解式):

@SentinelResource(
    value = "createOrder",
    blockHandler = "createOrderBlockHandler",  // 限流降级
    fallback = "createOrderFallback"          // 异常降级
)
public Order createOrder(OrderDTO dto) {
    // 正常业务逻辑
}

// 限流时的降级方法
public Order createOrderBlockHandler(OrderDTO dto, BlockException e) {
    throw new BusinessException("当前下单人数过多,请稍后再试");
}

// 服务异常时的降级方法
public Order createOrderFallback(OrderDTO dto, Throwable e) {
    // 记录到本地消息表,异步重试
    return Order.pending(dto);
}

17.2 依赖服务降级

外部依赖降级优先级:

依赖服务重要性降级方案影响
Redis高降级到DB查询性能下降50%
Elasticsearch中降级到MySQL搜索搜索功能受限
支付宝/微信支付高切换备用通道无影响
高德地图API中使用缓存数据位置可能不准
极光推送低记录日志,稍后重试通知延迟

Redis降级示例:

public User getUserById(Long userId) {
    try {
        // 优先查Redis
        return redisTemplate.get("user:" + userId);
    } catch (RedisException e) {
        log.warn("Redis故障,降级到数据库查询");
        // 降级到数据库
        return userMapper.selectById(userId);
    }
}

17.3 熔断器配置

熔断状态机:

关闭(Closed) → 打开(Open) → 半开(Half-Open) → 关闭
    ↓             ↓              ↓
正常请求      快速失败      尝试恢复

熔断参数配置:

服务失败率阈值熔断时间半开请求数
用户服务50%30秒5个
支付服务30%60秒3个
技师服务50%30秒5个

17.4 容灾演练计划

演练场景:

场景频率验证内容
MySQL主库宕机每季度主从自动切换,业务不中断
Redis集群故障每季度降级方案生效,性能可接受
单个微服务宕机每月其他服务正常,自动剔除故障节点
API网关故障每季度备用网关接管流量

十九、安全设计方案

19.1 接口安全

防刷策略(多层防护):

层级方案限制场景
L1 IP限流Nginx限流同IP 100次/分钟防爬虫
L2 用户限流Sentinel同用户 50次/分钟防刷单
L3 验证码图形/短信验证码敏感操作必须验证防机器人
L4 风控规则异常行为识别封禁异常账号防羊毛党

实现示例(注解式):

// 接口级别限流
@RateLimit(limit = 10, window = 60, key = "#phone")
public Result sendSms(String phone) {
    // 60秒内同一手机号最多10次
}

18.2 数据安全

敏感数据加密:

数据类型加密方式存储格式解密场景
手机号AES-256加密存储显示时脱敏
身份证号AES-256加密存储实名认证时
银行卡号AES-256加密存储提现时
健康数据AES-256加密存储查看详情时
用户密码BCrypt不可逆加密不解密,仅校验

数据脱敏规则:

手机号:138****1234
身份证:510***********1234
银行卡:6222************1234
邮箱:abc***@qq.com

18.3 认证授权增强

Token安全:

  • Token有效期:30天(可配置)
  • 刷新机制:距离过期7天内自动续期
  • 双Token机制:AccessToken(短期) + RefreshToken(长期)
  • 异地登录检测:同账号不同地区登录告警

权限控制:

角色层级:
- 超级管理员:所有权限
- 运营人员:订单管理、用户管理
- 客服人员:订单查看、客诉处理
- 财务人员:财务报表、提现审核

18.4 SQL注入与XSS防护

SQL注入防护:

  • 使用MyBatis预编译(#{}而非${})
  • 禁止拼接SQL
  • 数据库账号最小权限原则

XSS防护:

  • 输入过滤:过滤<script></iframe>等标签
  • 输出转义:显示时HTML转义
  • CSP策略:Content-Security-Policy响应头

18.5 安全检查清单

上线前必检项:

检查项要求检查方式
HTTPS全站HTTPS证书有效期检查
敏感信息不能硬编码代码扫描
SQL注入无拼接SQL代码审查
XSS漏洞输入过滤+输出转义渗透测试
权限校验所有接口鉴权自动化测试

二十、关键技术实现方案

20.1 AI智能推荐系统

技师推荐算法:

推荐分数 = 距离分(40%) + 评分分(30%) + 专业匹配度(20%) + 完单数(10%)

距离分: 
- 1km内: 100分
- 1-3km: 80分
- 3-5km: 60分
- 5-10km: 40分
- >10km: 0分

评分分:
- 5.0分: 100分
- 4.5-4.9分: 80分
- 4.0-4.4分: 60分
- <4.0分: 0分

专业匹配度:
- 主专业匹配: 100分
- 次专业匹配: 70分
- 不匹配: 30分

完单数加成:
- >1000单: 100分
- 500-1000单: 80分
- 100-500单: 60分
- <100单: 40分

体检报告AI分析:

  • 集成通义千问API
  • OCR识别体检报告文字
  • AI解读指标含义、识别异常
  • 生成通俗易懂的健康评估报告
  • 推荐适合的护理项目

19.2 即时通讯IM系统

架构设计(支持水平扩展):

┌─────────────────────────────────────────┐
│  客户端层(用户端/技师端)                     │
└─────────────────┬───────────────────────┘
                  │ WebSocket连接
┌─────────────────▼───────────────────────┐
│  负载均衡(Nginx)                          │
│  - 基于IP Hash分配连接                      │
└─────────────────┬───────────────────────┘
                  │
┌─────────────────▼───────────────────────┐
│  IM服务集群(多实例,可水平扩展)               │
│  - 每个实例维护本地连接表                     │
│  - 订阅Redis Pub/Sub接收消息               │
└─────────────────┬───────────────────────┘
                  │
┌─────────────────▼───────────────────────┐
│  消息路由层(Redis Pub/Sub)                │
│  - channel: im:user:{userId}            │
│  - 消息广播到所有IM实例                      │
└─────────────────┬───────────────────────┘
                  │
┌─────────────────▼───────────────────────┐
│  消息存储层(MongoDB)                       │
│  - 聊天记录持久化(保留30天)                 │
│  - 离线消息队列                             │
└─────────────────────────────────────────┘

关键设计要点:

问题解决方案说明
水平扩展Redis Pub/Sub + 连接路由用户上线记录在Redis:user:{id}→{server_ip},消息通过Pub/Sub广播
消息必达ACK机制 + 离线队列客户端收到消息回复ACK,未收到存离线队列,上线后拉取
消息去重消息唯一ID每条消息生成UUID,客户端和服务端都做去重
敏感词过滤本地敏感词库 + 云端API高频词本地匹配(性能),低频词调用阿里云API

消息流程(优化版):

1. 用户A发送消息 → IM服务实例1
2. 敏感词过滤(本地词库 + 阿里云API)
3. 保存MongoDB(异步,不影响发送速度)
4. 查询Redis:用户B在哪个实例?
5. 在线 → 通过Redis Pub/Sub推送到实例2 → WebSocket推送
6. 离线 → 存离线队列 + 极光推送通知
7. 用户B上线 → 拉取离线消息(最近100条)

消息类型支持:

  • 文字消息:纯文本 + 表情
  • 图片消息:上传OSS → 返回缩略图URL + 原图URL
  • 语音消息:上传OSS → 返回URL + duration(支持语音转文字)
  • 位置消息:lat/lng坐标 + 地址描述
  • 订单卡片:order_id关联,显示订单摘要

19.3 优惠券系统

优惠券叠加规则引擎:

// 优惠券计算顺序
1. 先应用折扣券 (如9折)
2. 再应用满减券 (如满200减30)
3. 再应用会员折扣 (如会员9折)
4. 最后应用无门槛券

// 示例计算
原价: 300元
折扣券9折: 300 * 0.9 = 270元
满减券满200减30: 270 - 30 = 240元
会员折扣9折: 240 * 0.9 = 216元

优惠券防刷策略:

  • 领取限制: 每人每张优惠券限领1次
  • IP限制: 同IP每日领取限制10次
  • 设备指纹: 防止模拟器批量领取
  • 风控系统: 异常领取行为风控拦截

19.4 红包系统

红包雨实现:

1. Redis预热红包池: 
   - key: red_packet_rain:{activity_id}
   - value: List<{amount, id}>

2. 用户点击抢红包:
   - Redis LPOP弹出一个红包
   - 成功 → 写入user_red_packets表
   - 失败(池空) → 返回"手慢了"

3. 防止超抢:
   - 使用Redis原子操作
   - 每个用户限抢N次(Redis计数)

随机红包算法:

// 二倍均值法
总金额: 100元
总个数: 10个
平均值: 10元

每次随机: random(0.01, 平均值 * 2)
第1个: random(0.01, 20) = 15元, 剩余85元, 平均9.44元
第2个: random(0.01, 18.88) = 8元, 剩余77元, 平均9.625元
...

19.5 拼团系统

拼团状态机:

发起拼团 → 等待成团 → 成团成功 → 订单支付 → 订单完成
         ↓
      超时未成团 → 自动退款

成团逻辑:

  • Redis存储拼团进度: pintuan:{团ID} → {已参团人数}
  • 每人参团时 Redis INCR 原子递增
  • 达到要求人数 → 发送成团通知
  • 24小时未成团 → 定时任务自动退款

19.6 秒杀系统

高并发秒杀方案:

1. 缓存预热:
   - 秒杀开始前将商品库存加载到Redis
   - key: seckill:stock:{商品ID} → 库存数

2. 库存扣减:
   - Redis DECR原子递减
   - 扣减成功 → 允许下单
   - 扣减失败(库存<0) → 返回"已抢光"

3. 异步下单:
   - 发送消息到RabbitMQ
   - 消费者异步创建订单
   - 扣减数据库库存

4. 防止超卖:
   - Redis原子操作保证
   - 数据库库存二次校验
   - 分布式锁保护

19.7 实时位置追踪

技术方案:

  • 技师端: 每10秒上报位置(lat/lng)
  • 后端存储: Redis GEO数据结构
  • 用户端查询:
    • APP: 每30秒轮询
    • APP: WebSocket实时推送

Redis GEO命令:

// 技师上报位置
GEOADD nurses:location 116.404 39.915 nurse:123

// 查询技师位置
GEOPOS nurses:location nurse:123

// 计算距离
GEODIST nurses:location nurse:123 user:456 km

19.8 老带新师徒系统

提成计算逻辑:

-- 徒弟完单时触发
1. 查询师徒关系: 
   SELECT * FROM nurse_mentor_relations 
   WHERE apprentice_id = #{徒弟ID}

2. 计算提成:
   提成金额 = 订单金额 * 提成比例
   - 前6个月: 2%
   - 6-12个月: 1%
   - 12个月后: 0%

3. 师傅账户入账:
   INSERT INTO settlement_records
   (nurse_id, amount, type, order_id)
   VALUES (师傅ID, 提成金额, 'MENTOR_COMMISSION', 订单ID)

4. 推送通知师傅

邀请奖励发放:

  • 事件驱动: 徒弟达成条件 → 发送MQ消息
  • 营销服务消费消息 → 发放奖励
  • 支付财务服务 → 奖励金入账

19.9 物联网设备集成

设备数据同步:

1. 设备端:
   - 蓝牙/WiFi连接APP
   - 上报数据: {device_id, type, value, timestamp}

2. 后端处理:
   - 健康管理服务接收数据
   - 存储到MongoDB (时序数据)
   - Redis缓存最新数据

3. 异常预警:
   - 规则引擎判断异常 (如心率>120)
   - 触发预警 → RabbitMQ消息
   - IM消息服务 → 推送通知用户

支持设备类型:

  • 智能手环/手表: 心率、步数、睡眠
  • 血压计: 血压数据
  • 血糖仪: 血糖数据
  • 血氧仪: 血氧饱和度
  • 体温计: 体温数据

二十一、常见问题FAQ

Q1: 如何选择AT模式还是TCC模式? A: AT模式适用于大多数场景,简单易用;TCC模式适用于需要精确控制资源的场景,如余额扣减、库存扣减。

Q2: 如何保证消息队列的可靠性? A: 生产者确认、消费者手动ACK、死信队列三重保障。

Q3: 如何处理分布式事务超时? A: 控制事务粒度,避免长事务;非关键流程改用本地消息表+定时补偿。

Q4: 如何优化服务间调用性能? A: 批量接口、合理超时时间、请求压缩、连接池复用。

Q5: 如何保证配置安全? A: 敏感信息使用环境变量,Nacos配置加密,定期审计。

Q6: 如何快速定位线上问题? A: SkyWalking链路追踪+ELK日志查询+Spring Boot Admin监控。

Q10: 10个微服务如何支撑225个功能点? A: 通过合理的领域拆分和服务聚合,每个服务承载相关业务功能:

  • 用户服务(20+功能): 账户、家庭成员、地址、收藏等
  • 技师服务(25+功能): 技师管理、AI推荐、师徒关系等
  • 订单服务(25+功能): 订单、预约、追踪、打卡等
  • 支付财务(20+功能): 支付、退款、分账、提现、发票等
  • 健康管理(20+功能): 档案、日志、体检AI、物联网等
  • 营销服务(45+功能): 优惠券、积分、会员、红包、活动等
  • IM消息(15+功能): 即时通讯、推送、通知等
  • 商城服务(20+功能): 商品、购物车、订单、物流等
  • 搜索服务(5+功能): 技师搜索、商品搜索、热门搜索等
  • 运营管理(30+功能): 后台管理、审核、数据报表等

二十二、架构风险与优化建议(重要)

22.1 架构风险评估

已识别的高风险问题:

风险项风险等级影响优化建议优先级
分布式事务过度使用高性能降低10倍改用本地消息表+MQP0
支付回调幂等性缺失高可能重复扣款增加唯一索引+分布式锁P0
Redis单点故障高服务不可用部署Redis集群P0
缓存策略不完善中缓存穿透/击穿布隆过滤器+互斥锁P1
服务边界模糊中耦合度高明确数据归属P1
IM架构不清晰中无法水平扩展Redis Pub/Sub方案P2

风险影响评估:

如果不解决P0问题,预计每月损失:
- 支付问题导致纠纷:5-10万
- Redis故障停服:10万/次
- 性能问题导致用户流失:20-30万
总计:50-100万/月(按GMV 1000万计算)

21.2 性能优化建议

响应时间优化目标:

接口类型当前预估优化目标优化方案
用户登录300ms100ms缓存用户信息
技师列表500ms150msRedis预计算+ES搜索
创建订单1000ms300ms去掉分布式事务
支付接口2000ms500ms异步处理

数据库优化:

  • 读写分离:读操作占80%,分离后主库压力降低80%
  • 索引优化:关键查询字段添加索引(订单号、用户ID、技师ID)
  • 分页优化:避免深分页(offset>10000),使用游标分页

缓存优化:

  • 命中率目标:>80%(当前可能<50%)
  • 本地缓存+Redis两级缓存
  • 缓存预热:系统启动时加载热点数据

21.3 成本优化建议

当前成本:约18,000元/月

优化方案:

项目当前成本优化后节省优化方式
服务器13,300元8,000元40%Kubernetes混合部署
数据库1,500元1,200元20%冷热数据分离
第三方服务2,400元1,600元33%缓存优化+防刷
合计18,000元12,000元33%-

具体措施:

  1. 服务器:Kubernetes按需分配资源,非高峰期缩容
  2. 高德地图:缓存常用路线,减少60%调用
  3. 短信服务:图形验证码前置,减少40%恶意请求
  4. OSS存储:生命周期管理,30天后归档

二十三、架构总结与建议

23.1 架构优势

业务覆盖完整: 10个服务合理支撑225个功能点,无遗漏
技术栈现代化: Spring Boot 3.2 + JDK 17,未来5年不过时
运维复杂度可控: 10个服务运维成本合理,不会过度膨胀
性能可扩展: 关键服务(订单/IM/商城/搜索)可独立扩容
数据安全合规: 健康数据加密、实名认证、隐私保护完善

22.2 分期开发建议(优化版)

⚠️ 重要调整:MVP范围缩小,快速验证市场

第一期(1.5-2个月): MVP最小化(推荐)

🎯 核心目标:2个月内上线,快速验证核心业务闭环

服务范围(4个简化服务):

  1. 用户服务(简化版)

    • 手机号登录
    • 基本信息管理
    • 地址管理(1个地址即可)
    • ❌ 暂不实现:家庭成员、实名认证、收藏、浏览历史
  2. 技师服务(简化版)

    • 技师列表查询
    • 技师详情
    • 基础筛选(距离、价格、评分)
    • ❌ 暂不实现:AI推荐、在线状态、师徒关系
  3. 订单服务(含基础IM)

    • 创建订单
    • 订单支付
    • 状态流转(待支付→已支付→服务中→已完成)
    • 基础IM(文字消息,集成在订单服务内)
    • ❌ 暂不实现:位置追踪、套餐卡、长期预约
  4. 支付财务服务(简化版)

    • 微信支付
    • 支付回调
    • ❌ 暂不实现:分账、提现、支付宝

交付目标:

  • ✅ 用户能下单预约护理服务
  • ✅ 技师能接单提供服务
  • ✅ 完成支付流程
  • ✅ 基本的文字沟通
  • 🎯 总功能点:约60个(砍掉73%)

团队配置: 后端3人、前端2人、测试1人


第二期(1.5-2个月): 体验完善

服务扩展: 5. IM独立服务 - 从订单服务拆分,支持图片、语音 6. 健康管理服务(简化版) - 护理日志、基础健康档案 7. 营销服务(简化版) - 优惠券(无叠加)、基础积分

功能增强:

  • 订单服务:位置追踪、评价
  • 技师服务:在线状态、接单管理
  • 用户服务:实名认证、家庭成员

交付目标:

  • ✅ 完整IM体验
  • ✅ 护理日志记录
  • ✅ 基础营销能力
  • 🎯 总功能点:约120个

第三期(2-3个月): 运营增长

服务完善: 8. 商城服务 - 套餐购买、商品销售 9. 运营管理服务 - 后台管理、数据报表

功能增强:

  • 营销服务:会员体系、红包、签到
  • 健康管理:AI体检分析
  • 技师服务:老带新、师徒关系
  • 支付服务:分账、提现、支付宝

交付目标:

  • ✅ 完整运营能力
  • ✅ 商城业务闭环
  • ✅ 后台管理系统
  • 🎯 总功能点:约200个

第四期(按需迭代): 智能化升级

高级功能:

  • AI智能推荐
  • 物联网设备集成
  • 拼团、秒杀等复杂活动
  • 完整财务报表

分期对比:

方案第一期周期服务数量功能点风险推荐度
原方案3-4个月5个完整服务100+高(战线长,难验证)⚠️ 不推荐
优化方案1.5-2个月4个简化服务60低(快速上线)✅ 强烈推荐

服务器成本(月)

  • 开发环境:

    • ECS 4核8G × 3台 = 1500元
    • MySQL/Redis/RabbitMQ = 800元
    • 小计: 2300元/月
  • 生产环境:

    • ECS 8核16G × 6台 (10服务+基础设施) = 6000元
    • RDS MySQL主从 = 1500元
    • Redis集群 = 1200元
    • MongoDB = 800元
    • RabbitMQ集群 = 1000元
    • Elasticsearch = 1500元
    • 负载均衡SLB = 500元
    • OSS对象存储 = 300元
    • CDN流量 = 500元
    • 小计: 13,300元/月
  • 第三方服务成本(月):

    • 高德地图API = 500元
    • 极光推送 = 300元
    • 阿里云短信 = 500元
    • 实名认证 = 300元
    • 通义千问API = 800元
    • 支付手续费(按交易额) = 动态
    • 小计: 2,400元/月

总月成本: 约 18,000元/月

22.5 风险控制

风险类型应对措施
技术风险核心技术采用成熟方案(Spring Cloud Alibaba),降低技术风险
性能风险关键路径(订单/支付)压测,Redis缓存,异步处理
数据风险主从备份,定期备份,异地容灾
安全风险数据加密、权限控制、WAF防护、漏洞扫描
人员风险代码标准、文档完善、知识传承

22.6 关键指标监控

业务指标:

  • DAU(日活)、订单量、GMV
  • 支付成功率、订单完成率
  • 技师在线率、接单响应时间
  • 用户复购率、技师留存率

技术指标:

  • API响应时间(P95 < 1秒)
  • 服务可用性(>99.9%)
  • 错误率(<0.1%)
  • 数据库慢查询(< 1秒)

22.7 后续优化方向

第一阶段(上线前):

  • 完成核心功能开发
  • 压力测试和性能优化
  • 安全测试和漏洞修复

第二阶段(上线后3个月):

  • 数据驱动优化(基于埋点数据)
  • 根据用户反馈迭代
  • 性能监控和容量规划

第三阶段(上线后6个月):

  • AI能力增强(智能推荐、智能客服)
  • 多城市扩展
  • 生态合作(保险、医院)

二十四、参考资料

  • Spring Boot 3.2 官方文档
  • Spring Cloud 2023 官方文档
  • Nacos 官方文档
  • Sa-Token 官方文档
  • Seata 官方文档

文档版本: v3.3 (新增服务边界约束章节) 最后更新: 2025-12-03 架构设计: 微服务架构最佳实践 + 架构复盘优化 服务规模: 10个微服务,支撑225个功能点 技术栈: Spring Boot 3.2 + Spring Cloud Alibaba + JDK 17 维护者: 麦瓣健康技术团队

v3.3 更新内容 (2025-12-03):

  • ✅ 新增"第三章:服务边界与依赖约束"
  • ✅ 明确微服务 jar 依赖隔离原则
  • ✅ 规范服务间通信方式(HTTP/gRPC、消息队列、事件总线)
  • ✅ 定义公共能力下沉策略(maiban-common 基础库)
  • ✅ 完善依赖检测与验证机制(本地检查 + CI/CD 验证)
  • ✅ 统一调整后续所有章节编号(章节总数从23章增至24章)

v3.2 更新内容 (2025-11-07):

  • ✅ 修复章节编号重复问题(第892行"九"改为"十")
  • ✅ 统一调整后续所有章节编号(十→十一,十一→十二,...,二十二→二十三)
  • ✅ 更新章节交叉引用(架构风险提示指向第二十一章)
  • ✅ 移除maiban-mbg微服务模块(仅保留作为开发工具)

v3.1 更新内容 (2025-10-24):

  • ✅ 新增"1.3 基础设施服务端口总览"章节
  • ✅ 补充完整的基础设施服务端口配置表(MySQL、Redis、Nacos等8个服务)
  • ✅ 添加服务访问地址快速参考表
  • ✅ 修正搜索服务端口配置(8086 → 8089)
  • ✅ 增加安全提示说明

v3.0 更新内容 (2025-10-18):

  • ✅ 补充Redis缓存策略详解(防穿透/击穿/雪崩)
  • ✅ 补充降级容灾方案(限流、熔断、容灾演练)
  • ✅ 补充安全设计方案(防刷、加密、权限)
  • ✅ 优化分布式事务方案(优先最终一致性)
  • ✅ 优化IM架构设计(支持水平扩展)
  • ✅ 调整MVP分期建议(第一期2个月上线)
  • ✅ 新增架构风险评估章节
  • ✅ 新增性能优化和成本优化建议
在 GitHub 上编辑此页
最后更新: 2025/12/3 16:43
贡献者: helayD, David, Claude, Claude Code
Next
/Docker部署指南.html