从 Docker 到 Doris:建立后端基础设施全景图
2026/8/26 20:40:52 网站建设 项目流程

最近需要快速理解一个 Spring Boot、Spring Cloud 项目,并准备借助 AI 新增一个项目。因为 Java 基础还不扎实,我给自己定的目标不是短期内独立手写所有代码,而是先达到三个标准:

  1. 能解释每个基础设施组件解决什么问题;
  2. 能在代码和配置中找到它的入口;
  3. 能和研发人员沟通,也能判断 AI 生成的方案是否合理。

我集中学习了 Docker、Docker Compose、Kubernetes、Kafka、RabbitMQ、OceanBase 和 Doris。最大的收获不是记住七套定义,而是发现它们可以放进一张非常清楚的系统地图。

一、先别背名词:后端系统只是在解决三类问题

第一类问题是:应用怎样以一致的方式运行?

本地环境、测试环境和生产环境不能各装一套不同版本的 Java 与依赖。Docker 用镜像统一交付;Compose 组织一台机器上的多个容器;K8s 在集群中管理大量容器。

第二类问题是:服务之间怎样异步协作?

一次请求不可能永远同步等待所有下游。Kafka 保存可以被多个系统独立读取和重放的事件,RabbitMQ 把需要处理的消息路由到合适的任务队列。

第三类问题是:数据怎样保存和使用?

订单、账户和库存要求事务准确;报表和指标要求快速扫描大量数据。MySQL、OceanBase 偏前者,Doris 偏后者。

从这三个问题出发,再看具体产品就不容易混乱。

二、Docker、Compose、K8s:从一个容器到整个集群

1. Docker:统一应用交付物

Dockerfile 像一张配方,说明基础镜像是什么、JAR 放在哪里、用什么命令启动。构建结果是镜像,镜像运行后才是容器。

FROM eclipse-temurin:21-jre WORKDIR /app COPY target/order-service.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]

一开始我把 Docker 理解成“把本地项目打包成可以直接运行的应用”,这个方向没错,但还要加上两个边界:

  • 镜像是只读模板,容器是运行实例;
  • 容器中的临时数据可能随容器删除,因此数据库等持久数据要放到 Volume。

2. Docker Compose:组织一台机器上的多个容器

一个 Spring Cloud 项目可能同时依赖 Gateway、订单服务、MySQL 和 RabbitMQ。Compose 可以把它们写进一个 YAML,一次启动整套本地环境。

它最适合开发、联调、演示和简单单机部署。服务之间可以用服务名通信,但depends_on主要表示启动顺序,不代表数据库已经做好接收请求的准备。

3. Kubernetes:维护集群期望状态

K8s 最重要的概念不是“多服务器部署”,而是期望状态

例如我声明订单服务需要三个副本:

期望状态:3 个 Pod 实际状态:2 个 Pod 控制器动作:再创建 1 个 Pod

Deployment 管理副本和发布,Service 给变化的 Pod 提供稳定地址,ConfigMap 和 Secret 承载配置,探针判断应用是否存活、是否已经可以接收流量。

因此可以这样记:

Docker:运行一个容器 Compose:组织一台机器上的多个容器 K8s:在集群中持续维护容器化应用的期望状态

三、Kafka 与 RabbitMQ:事件档案和任务派送

这是我学习过程中最容易混淆的一组。

1. Kafka 更像可重放的事件档案

生产者把事件追加到 Topic 的 Partition。消费者通过 offset 记录自己在分区中读到了哪里,多个 Consumer Group 可以各自读取同一批事件。

例如订单创建后:

OrderCreated ├── 风控消费组 ├── 积分消费组 ├── 推荐消费组 └── Doris 数据同步消费组

如果 Doris 需要重建近七天的数据,可以调整消费位置重新读取历史事件。这种需要保留、重放和多个下游独立订阅的场景,通常更偏 Kafka。

2. RabbitMQ 更像任务派送中心

RabbitMQ 通常把消息发送给 Exchange,再根据 Routing Key 和 Binding 路由到 Queue。消费者处理完成后发送 ACK,消息随后从队列移除。

例如:

支付成功 ↓ SendPaymentSms ↓ 短信队列 ↓ 某一个短信消费者处理 ↓ 成功 ACK;多次失败进入死信队列

需要灵活路由、任务确认、重试和死信处理的场景,通常更偏 RabbitMQ。

3. 不是“Kafka 能做什么、RabbitMQ 不能做什么”

Kafka 也能在一个消费组内把任务分摊给多个消费者;RabbitMQ 也能绑定多个队列实现发布订阅。两者存在能力重叠。

真正的判断维度是:

  • 消息是否需要保留和重放?
  • 多个下游是否需要独立消费?
  • 是否需要复杂路由?
  • 任务是否强调 ACK、重试和死信处理?

四、我对 offset 最大的一次误解

学习时遇到一道题:优惠券已经发放,但 Kafka offset 还没提交,消费者突然宕机,恢复后会发生什么?

我最初想到的是多节点备份和定时写入磁盘。这个回答混淆了两个层次:

  • Kafka Broker 的副本和磁盘负责保存消息;
  • Consumer 的 offset 负责记录读取进度。

消息其实还在 Kafka 中。因为 offset 没有提交,消费者恢复后会再次读到同一条事件,于是可能重复发放优惠券。

真正需要的是业务幂等。

例如每个订单只允许领取一次某类优惠券,可以使用:

UNIQUE(order_id, coupon_type)

消费者再次收到消息时,如果唯一记录已经存在,就不再发券,但仍把本次消费视为成功并提交 offset。

还有一个容易忽略的并发问题:不能只“先查询是否处理过,再决定是否发放”。两个消费者可能同时查询,都看到未处理。数据库唯一约束才是最后防线。

这让我理解了一个常见取舍:

先提交 offset 可能丢业务;先完成业务再提交 offset 可能重复。工程上常选择至少一次投递,再用幂等消除重复影响。

五、MySQL、OceanBase、Doris:业务事实和分析结果

1. MySQL 与 OceanBase 偏 OLTP

创建订单、扣减库存和修改支付状态,需要频繁增删改查、事务和低延迟点查。MySQL 和 OceanBase 都适合这类在线交易处理。

OceanBase 是独立的分布式关系型数据库,并提供 MySQL 兼容模式。它的价值主要在原生分布式扩展、高可用和大规模事务能力,但不能简单理解成“任何场景都比 MySQL 更好”。规模较小、架构简单时,MySQL 通常更轻量。

2. Doris 偏 OLAP

“查询某一笔订单是否支付”更像 OLTP;“统计过去一年每个地区每天的销售额”则需要扫描和聚合大量数据,更适合 Doris。

Doris 兼容 MySQL 协议和一部分 SQL 使用方式,因此可以用 JDBC、数据库客户端和 BI 工具连接,但连接方式相似不代表用途相同。

典型数据链路可以是:

订单写入 MySQL / OceanBase ↓ Kafka / CDC / 同步任务 ↓ Doris ↓ 报表、趋势、排行

一句话记忆:MySQL 或 OceanBase 把每笔生意记准确,Doris 从大量生意中总结规律。

六、把七个组件放回一条订单链路

用户请求 ↓ Spring Cloud Gateway ↓ Spring Boot 订单服务 ↓ MySQL / OceanBase 保存订单事务 ↓ Kafka 发布 OrderCreated ├── 风控 ├── 积分 └── 同步到 Doris 做分析 发送短信、邮件等任务 ↓ RabbitMQ ↓ 任务消费者处理并 ACK

Docker 把这些应用制作成镜像。开发环境可能用 Compose 启动一整套依赖,测试和生产环境可能交给 K8s 调度。

这只是一张学习用的示意图,真实项目必须结合目录、依赖、配置和调用链验证,不能看到技术名词就套固定架构。

七、接下来看真实项目时,我会先找什么

我不会从某个业务类开始逐行阅读,而是先找组件“接缝”:

  • Docker:Dockerfile、基础镜像、JAR、端口、启动命令;
  • Compose:compose.yml、services、ports、volumes、healthcheck;
  • K8s:Deployment、Service、镜像、副本、探针、ConfigMap;
  • Kafka:spring-kafkabootstrap-servers@KafkaListener、topic、group-id;
  • RabbitMQ:spring-boot-starter-amqp、Exchange、Queue、Routing Key、@RabbitListener
  • OceanBase:数据源 URL、JDBC 驱动、MyBatis/JPA、事务、表和索引;
  • Doris:分析数据源、聚合 SQL、Kafka 导入、Stream Load、分区分桶。

然后固定追问六件事:谁写入、谁读取、失败如何重试、是否可能重复、数据以谁为准、如何观察健康状态。

这次速成让我建立了概念地图,但还不能算真正看懂项目。下一步是把真实项目的模块目录、启动类、构建文件和配置拿出来,把每一个概念映射到实际文件和调用链中。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询