一、整体架构理解

这是一个分布式微服务架构,可以类比为一个大型购物中心:

  • Java服务集群 = 多个收银台(处理业务)
  • 负载均衡 = 门口的引导员(分流顾客)
  • Redis = 快速取货区(缓存)
  • MySQL/MongoDB = 大仓库(持久化存储)
  • Kafka = 传送带(异步处理)
  • Apollo = 管理规则手册(配置中心)
  • Docker = 标准化的工作间(容器)

二、各组件详细解释

1️⃣ Java服务集群(核心大脑)

是什么?

  • 你的业务代码运行的地方
  • 用Spring Boot等框架开发的应用程序

做什么?

接收请求 → 处理业务逻辑 → 调用数据库 → 返回结果

为什么要集群?

  • 单点故障问题:一台服务器挂了,整个系统瘫痪
  • 性能瓶颈:一台服务器处理不了高并发
  • 解决方案:部署3台、5台甚至更多服务器,互为备份

举例

用户A请求 → 服务器1处理
用户B请求 → 服务器2处理
用户C请求 → 服务器3处理
如果服务器1挂了,用户A的下一次请求会被分配到服务器2或3

2️⃣ Apollo配置中心(规则手册)

是什么?

  • 携程开源的配置管理平台

解决什么问题?

传统方式的痛点

配置写在application.properties里
修改配置 → 重新打包 → 重新部署 → 重启服务(停机时间)
有10台服务器 → 要改10次配置文件

使用Apollo后

配置存在Apollo服务器
修改配置 → 点击发布 → 所有服务自动更新(无需重启)

配置示例

# 数据库连接
db.url=jdbc:mysql://192.168.1.100:3306/mydb
db.username=root
db.password=123456

# Redis配置
redis.host=192.168.1.101
redis.port=6379

# Kafka配置
kafka. servers=192.168.1.102:9092

实际场景

双11活动:需要临时调整限流阈值
不用Apollo:修改代码 → 重新发布 → 可能错过活动高峰
用Apollo:页面上修改配置 → 立即生效

3️⃣ Redis缓存(快速通道)

是什么?

  • 内存数据库,读写速度极快(微秒级)

为什么需要?

性能对比

Redis读取:0.1毫秒
MySQL读取:10毫秒(慢100倍)

典型使用场景

场景1:热点数据缓存

// 查询商品详情
public Product getProduct(String id) {
    // 1. 先查Redis
    Product product = redis.get("product:" + id);
    
    if (product != null) {
        return product;  // 缓存命中,直接返回
    }
    
    // 2. Redis没有,查MySQL
    product = mysql.query("SELECT * FROM product WHERE id = ?", id);
    
    // 3. 写入Redis,下次直接用
    redis.set("product:" + id, product, 3600);  // 缓存1小时
    
    return product;
}

场景2:分布式锁

// 防止超卖(多台服务器同时操作库存)
public boolean buyProduct(String productId) {
    // 尝试获取锁
    boolean locked = redis.setNX("lock:" + productId, "locked", 10);
    
    if (! locked) {
        return false;  // 有其他服务器正在处理
    }
    
    try {
        // 扣减库存
        int stock = getStock(productId);
        if (stock > 0) {
            updateStock(productId, stock - 1);
            return true;
        }
    } finally {
        redis.delete("lock:" + productId);  // 释放锁
    }
}

场景3:会话共享

用户登录 → 服务器1 → Session存Redis
用户刷新 → 服务器2 → 从Redis读Session → 还是登录状态

4️⃣ Kafka消息队列(传送带)

是什么?

  • 高性能的消息队列系统

解决什么问题?

问题1:异步处理

❌ 同步方式(慢):
用户注册 → 写数据库(50ms) → 发邮件(2000ms) → 发短信(1000ms) → 返回
总耗时:3050ms

✅ 异步方式(快):
用户注册 → 写数据库(50ms) → 发消息到Kafka(5ms) → 返回
总耗时:55ms
后台慢慢处理邮件和短信
// 用户注册
public void register(User user) {
    // 1. 保存用户信息
    mysql.save(user);
    
    // 2. 发送消息到Kafka(立即返回)
    kafka.send("user-register", user);
    
    // 3. 立即返回给用户
    return success();
}

// 另一个消费者监听Kafka
@KafkaListener(topic = "user-register")
public void handleRegister(User user) {
    // 异步发送邮件
    emailService.sendWelcomeEmail(user);
    // 异步发送短信
    smsService.sendWelcomeSMS(user);
}

问题2:削峰填谷

秒杀场景:
瞬间10万请求 → 直接打到数据库 → 数据库崩溃

使用Kafka:
10万请求 → 放入Kafka队列 → 按每秒1000的速度慢慢处理

问题3:系统解耦

订单系统创建订单后需要:
- 库存系统扣减库存
- 积分系统增加积分
- 物流系统创建运单
- 通知系统发消息

❌ 直接调用:订单系统要知道所有系统的接口
✅ 使用Kafka:订单系统只管发消息,其他系统各自监听

5️⃣ MySQL关系型数据库(核心仓库)

适合存什么?

  • 需要事务的数据(订单、支付、账户)
  • 需要复杂查询的数据(多表关联)
  • 核心业务数据

示例

-- 订单表
CREATE TABLE orders (
    id BIGINT PRIMARY KEY,
    user_id BIGINT,
    product_id BIGINT,
    amount DECIMAL(10,2),
    status VARCHAR(20),
    create_time DATETIME
);

-- 事务保证:扣款和创建订单要么都成功,要么都失败
BEGIN TRANSACTION;
    UPDATE account SET balance = balance - 100 WHERE user_id = 123;
    INSERT INTO orders VALUES (...);
COMMIT;

6️⃣ MongoDB文档数据库(灵活仓库)

适合存什么?

  • 日志数据(访问日志、操作日志)
  • 非结构化数据(商品评论、用户动态)
  • 频繁变化的数据(不需要固定表结构)

对比

MySQL存储评论:
需要提前设计表结构,字段固定
ALTER TABLE 修改表结构很麻烦

MongoDB存储评论:
{
    "user":  "张三",
    "content": "商品不错",
    "images": ["url1", "url2"],
    "tags": ["好评", "推荐"]  // 随时可以加新字段
}

7️⃣ Docker容器(标准化包装)

解决什么问题?

❌ 传统部署:
开发环境:Windows + JDK8 + MySQL5.7 → 运行正常
测试环境:Linux + JDK11 + MySQL8.0 → 各种报错
生产环境:又是另一套环境 → 又要调试

✅ Docker部署:
开发:打包成Docker镜像
测试:运行同一个镜像
生产:还是同一个镜像
→ 环境完全一致

Dockerfile示例

FROM openjdk:11
COPY myapp.jar /app/
EXPOSE 8080
CMD ["java", "-jar", "/app/myapp.jar"]

一键部署

docker run -d -p 8080:8080 myapp: latest

三、完整请求流程示例

场景:用户查看商品详情

sequenceDiagram
    participant U as 用户
    participant LB as 负载均衡
    participant J as Java服务
    participant A as Apollo
    participant R as Redis
    participant My as MySQL
    participant K as Kafka
    participant Mo as MongoDB

    Note over J,A: 【启动阶段】
    J->>A: 我要拉取配置
    A-->>J: 给你数据库地址、Redis地址等
    
    Note over U,R: 【第一次请求 - 缓存未命中】
    U->>LB: GET /product/12345
    LB->>J: 转发到服务器2
    J->>R: 查Redis:  product:12345
    R-->>J: 返回null(缓存没有)
    J->>My: SELECT * FROM product WHERE id=12345
    My-->>J: 返回商品数据
    J->>R: 存入Redis,过期时间1小时
    J->>K: 发送消息:用户查看了商品12345
    J-->>U: 返回商品详情(耗时150ms)
    
    Note over K,Mo: 【异步处理】
    K->>J: 消费消息
    J->>Mo: 记录浏览日志到MongoDB
    
    Note over U,R: 【第二次请求 - 缓存命中】
    U->>LB: GET /product/12345
    LB->>J: 转发到服务器1
    J->>R: 查Redis: product:12345
    R-->>J: 返回商品数据
    J-->>U: 返回商品详情(耗时5ms)

场景:用户下单(完整流程)

graph TD
    A[用户提交订单] --> B{负载均衡}
    B --> C[Java服务实例1]
    
    C --> D{检查Redis缓存: <br/>用户登录状态}
    D -->|未登录| E[返回错误]
    D -->|已登录| F{Redis分布式锁:<br/>防止重复下单}
    
    F -->|获取锁失败| G[返回: 请勿重复提交]
    F -->|获取锁成功| H[开始处理订单]
    
    H --> I[MySQL事务开始]
    I --> J[检查库存]
    J -->|库存不足| K[事务回滚]
    J -->|库存充足| L[创建订单记录]
    L --> M[扣减库存]
    M --> N[扣减用户余额]
    N --> O[事务提交]
    
    O --> P[发送消息到Kafka: <br/>order-created]
    P --> Q[释放Redis锁]
    Q --> R[返回成功给用户]
    
    P --> S[Kafka消费者1:<br/>库存系统]
    P --> T[Kafka消费者2:<br/>积分系统]
    P --> U[Kafka消费者3:<br/>物流系统]
    
    S --> V[更新库存缓存]
    T --> W[增加积分]
    U --> X[创建运单]
    
    V --> Y[MongoDB记录操作日志]
    W --> Y
    X --> Y
    
    style A fill:#e1f5ff
    style C fill:#e8f5e9
    style D fill:#ffebee
    style I fill:#e3f2fd
    style P fill:#fff3e0
    style Y fill:#e8f5e9

四、关键协作模式

1. 缓存模式(提升性能)

请求 → Redis(快) → MySQL(慢但准确)
         ↓ 命中         ↓ 未命中
       直接返回      查DB+回写缓存

2. 读写分离(高并发)

写操作 → MySQL主库 → 同步到从库
读操作 → MySQL从库(多个)

3. 最终一致性(异步处理)

核心操作(下单)→ 立即写MySQL(强一致)
次要操作(发邮件)→ Kafka异步(最终一致)

4. 配置热更新

修改Apollo配置 → 推送到所有Java服务 → 无需重启生效

五、为什么这样设计?

高可用

  • Java服务集群:一台挂了其他顶上
  • Redis/MySQL主从:主库挂了从库升级
  • Kafka集群:消息不会丢失

高性能

  • Redis缓存:减少数据库压力
  • Kafka异步:不阻塞主流程
  • 负载均衡:分散请求压力

可扩展

  • 流量大了:加服务器
  • 数据多了:数据库分库分表
  • 配置改了:Apollo立即生效

易维护

  • Docker:环境一致
  • Apollo:配置集中管理
  • 日志统一存MongoDB

六、技术选型对比

组件 为什么选它 替代方案
Redis 性能最好,功能丰富 Memcached(功能少)
Kafka 高吞吐,持久化 RabbitMQ(吞吐低)、RocketMQ
MySQL 成熟稳定,生态好 PostgreSQL、Oracle
MongoDB 灵活schema,高性能 Elasticsearch、Cassandra
Apollo 国内流行,中文文档 Nacos、Spring Cloud Config
Docker 事实标准 Podman、containerd