CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
软件架构师入门/课时/云与设计模式
RawBlame
课时目录12 节

软件架构师入门

  1. 01软件架构是什么
  2. 02架构师软技能
  3. 03设计模式与原则
  4. 04架构风格
  5. 05数据架构
  6. 06API 与集成
  7. 07安全架构
  8. 08云与设计模式
  9. 09网络基础
  10. 10技术栈选型
  11. 11治理与方法论
  12. 12综合练习

云与设计模式

IaC、容器、CI/CD、Mesh。

35 分钟

云与设计模式

这一课你将能做到

  1. 写出本站的 Dockerfile 和 K8s Deployment 清单,理解每个字段的作用
  2. 设计一条完整的 CI/CD 流水线:代码提交到生产发布的全部环节
  3. 说出至少 5 个云设计模式(熔断、重试、舱壁等)并说明本站哪里用得上

为什么要学

云原生改变了架构的边界条件:以前「加服务器」要采购流程几个月,现在一条命令扩容 10 台。架构师必须理解云的能力边界,才能设计出「弹得起、挂不了、回得去」的系统。

人话:传统部署像自己盖房子——一砖一瓦都自己管;云像住酒店——房间随便换、保洁有人做,但你得遵守酒店的规矩(无状态、可中断、声明式配置)。

先建立图像

本站上云演进路线:

【阶段一:单机部署】              【阶段二:容器化】
一台 ECS:                       Dockerfile → 镜像仓库
├── java -jar app.jar           K8s 集群:
├── MySQL                       ├── Deployment(app) × 3 副本
├── Redis                       ├── Service(负载均衡)
└── Nginx                       ├── HPA(CPU>70% 自动扩容)
                                └── RDS + 云 Redis(托管)
【阶段三:完整云原生】
GitHub Push → CI(测试/构建镜像) → CD(金丝雀发布)
           → 监控(Prometheus) → 告警 → 自动回滚

跟着做

步骤 1:容器化本站应用

# 多阶段构建:编译和运行分离,镜像从 500MB 降到 200MB
FROM maven:3.9-eclipse-temurin-21 AS build
COPY pom.xml .
COPY src ./src
RUN mvn package -DskipTests

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build target/app.jar app.jar
# 关键:非 root 运行 + JVM 容器感知
USER 1000
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75", "-jar", "app.jar"]

步骤 2:K8s 部署清单

apiVersion: apps/v1
kind: Deployment
metadata:
  name: course-service
spec:
  replicas: 3                     # 3 副本保证高可用
  strategy:
    rollingUpdate:
      maxSurge: 1                 # 滚动更新:先多启 1 个
      maxUnavailable: 0           # 全程不减少可用实例
  template:
    spec:
      containers:
      - name: app
        image: registry/course-service:v1.2.0
        resources:
          requests:               # 调度依据:保证分到的资源
            cpu: 500m
            memory: 512Mi
          limits:                 # 上限:防止吃光节点
            cpu: "1"
            memory: 1Gi
        readinessProbe:           # 就绪探针:没就绪不接流量
          httpGet:
            path: /actuator/health/readiness
            port: 8080
        livenessProbe:            # 存活探针:挂了自动重启
          httpGet:
            path: /actuator/health/liveness
            port: 8080

步骤 3:CI/CD 流水线

代码 Push
  → 阶段1 构建:编译 + 单元测试(失败即终止)
  → 阶段2 质检:SonarQube 扫描 + 依赖漏洞检查
  → 阶段3 打包:docker build + 推镜像仓库(tag 用 commit hash)
  → 阶段4 部署测试环境:自动部署 + 接口自动化测试
  → 阶段5 生产金丝雀:先发布 1 个副本 → 观察 10 分钟指标
  → 阶段6 全量:无异常则滚动更新全部;有异常自动回滚

讲清楚要点

  1. 云设计模式是应对「云会挂」的现实:云厂商 SLA 99.95% 意味着每月允许 22 分钟故障。设计必须假设任何单点都会挂:重试(瞬时故障)、熔断(持续故障)、舱壁(隔离故障域)。
  2. 无状态是云原生的入场券:Session 存 Redis 不存本地内存,文件存对象存储不写本地磁盘。只有这样,Pod 才能随意被销毁重建、水平扩容。
  3. 声明式 > 命令式:K8s 的 YAML 描述「我要 3 个副本」,而不是「启动 3 个进程」。系统持续向期望状态收敛,挂了自动拉起——这就是声明式的自愈能力。
  4. Serverless 的边界:FaaS 适合事件驱动、突发流量、低频任务(本站可以用函数处理「课程封面图压缩」);不适合长运行任务、低延迟要求、有状态服务。
  5. Service Mesh 解决什么:把熔断、限流、链路追踪、加密从业务代码剥离到 Sidecar 代理(Istio)。代价是架构复杂度大增——服务少于 20 个时,用 Spring Cloud 组件足够。

你可能会懵的地方

  • Docker 和 K8s 是什么关系? Docker 是集装箱(打包标准),K8s 是港口调度系统(决定集装箱放哪艘船、船沉了怎么转移)。可以只用 Docker 不用 K8s(小项目 docker-compose 就够),但 K8s 管理的一定是容器。

  • 虚拟机部署好好的,为什么要容器化? 三个核心价值:环境一致性(开发/测试/生产同一镜像,消灭「我本地是好的」)、启动速度(秒级 vs 分钟级,弹性伸缩的前提)、资源利用率(一台机器跑几十个容器)。

  • 金丝雀发布和蓝绿发布区别? 蓝绿:两套完整环境,流量一次性切换,回滚快但资源翻倍。金丝雀:新版本先接 5% 流量,逐步放大,发现问题影响面小。本站用金丝雀,因为 K8s 原生支持且省资源。

  • 托管服务(RDS、云 Redis)比自己搭贵,值吗? 算总账:RDS 贵 30%,但自动备份、主从切换、监控告警、补丁升级都省了。小团队没有专职 DBA,托管几乎总是更划算——你的时间比机器贵。

  • IaC(基础设施即代码)解决什么痛点? 手工控制台点出来的环境,没人记得配了什么、无法复现、无法评审。Terraform/Pulumi 把基础设施写成代码:环境可一键重建、变更可 Code Review、多环境一致性有保证。

错法对照

错法问题正解
容器里跑多进程(app+nginx+agent)违背单一职责,探针无法判断健康一容器一进程,辅助功能用 Sidecar
用 latest 标签部署不知道线上跑的是哪个版本镜像 tag 用 git commit hash
没配 resources requests调度失衡,节点资源被挤爆必须配 requests/limits
探针路径是业务接口业务慢导致误判,引发重启雪崩专用健康端点,和业务解耦
有状态服务直接上 DeploymentPod 重建后数据丢失MySQL 等用 StatefulSet 或直接托管

卡点急救

  1. Pod 一直 CrashLoopBackOff:kubectl logs 看启动日志 + kubectl describe pod 看事件,90% 是配置错误(环境变量、连接串)或 OOM(limits 太小)。
  2. 发布后部分请求 502:滚动更新时旧 Pod 还没处理完请求就被杀。解法:preStop 钩子先 sleep 几秒等 LB 摘除,应用实现优雅停机(Spring Boot 的 server.shutdown=graceful)。
  3. HPA 扩容不及时:HPA 从检测到扩容完成要几分钟,突发流量扛不住。解法:基于 QPS 指标扩缩(而非 CPU),或活动前手动预扩容。

面试常问

  • K8s 的核心组件和一次部署的完整流程? 答题路径:kubectl 提交 YAML → API Server 接收存 etcd → Scheduler 选节点(看 requests)→ Kubelet 拉镜像启动容器 → Controller 持续对比期望与实际状态。组件记四个:API Server(总入口)、etcd(存储)、Scheduler(调度)、Controller Manager(控制循环)。加分:提到 readinessProbe 控制 Service 流量接入时机。

  • 什么是熔断和降级?怎么实现的? 熔断:调用下游失败率达到阈值,熔断器打开,直接走 fallback 不再调用,半开状态试探恢复。类比电路保险丝——防止故障蔓延。降级:系统压力大时主动关掉非核心功能(本站大促时关闭推荐模块,保住下单链路)。实现:Resilience4j/Sentinel,核心参数是滑动窗口、错误率阈值、恢复时长。

  • 如何设计一个高可用系统? 分层答:接入层(多地域 DNS + LB)、应用层(多副本无状态 + 跨可用区)、数据层(主从 + 自动切换 + 定期备份演练)、架构层(熔断限流降级 + 故障隔离)。最后强调:高可用是设计出来的,也是演练出来的——没做过故障演练的容灾预案等于没有。

自测三问

  1. 为什么容器化要求应用无状态?本站的 Session 改造方案是什么?
  2. readinessProbe 和 livenessProbe 配错(比如配反了)会发生什么?
  3. 如果不用 K8s,3 个微服务的项目用什么部署方案最合理?

小结一句话

云原生架构的核心是「假设一切会挂」:用无状态和声明式获得弹性,用熔断重试舱壁消化故障,用 CI/CD 和金丝雀控制变更风险。

延伸

  • 《云原生模式》(Cloud Native Patterns, Cornelia Davis)
  • 12-Factor App——云原生应用的十二要素
  • K8s 官方文档:Production-Grade 章节
  • 下一课:网络基础——OSI、HTTP/TLS 与代理,排查线上问题的语言。
加载本节练习…
← 上一课安全架构下一课 →网络基础