.. _chapter1:

========================
第 1 章 度量驱动开发概论
========================

.. admonition:: 本章你将学到

   - 微服务架构为什么需要度量
   - 什么是度量驱动开发（MDD），它与传统监控有何不同
   - AI 时代服务架构的演进与度量的新挑战
   - MDD 方法论的全景图和核心框架
   - 度量驱动开发与 TDD、活文档的协同关系


开篇故事
========

   *线上出了问题，日志里没有明显错误，CPU 和内存看起来都正常。
   你在十几个微服务之间来回排查，翻日志、加临时打印、重启服务碰运气……
   折腾了很久，才发现问题出在一个不起眼的地方——连接池耗尽、下游超时、
   或者某个配置被悄悄改了。*

   *如果有完善的度量体系——连接池使用率、请求排队时间、上下游延迟的关联分析——
   这个问题本可以在几分钟内定位。*

这个场景，几乎每个做过微服务的工程师都经历过。
系统越复杂，"不知道问题出在哪里"的痛苦就越深。
度量驱动开发，正是为了解决这个痛苦而生的方法论。


1.1 从单体到微服务：可观测性的挑战
====================================

1.1.1 微服务的优势与代价
-------------------------

微服务架构将一个大型应用拆分为多个小型、独立的服务，
每个服务围绕特定的业务能力构建，可以独立开发、部署和扩展。
这种架构带来了显著的优势，但也引入了新的复杂性：

.. list-table:: 单体架构 vs 微服务架构
   :header-rows: 1
   :widths: 20 40 40

   * - 维度
     - 单体架构
     - 微服务架构
   * - 开发效率
     - 初期高，后期低
     - 初期低，后期高
   * - 部署
     - 整体部署，风险集中
     - 独立部署，风险分散
   * - 技术栈
     - 统一，受限
     - 多样，灵活
   * - 故障影响
     - 一个模块崩溃，全局受影响
     - 故障隔离，影响范围可控
   * - **问题诊断**
     - **相对简单，一个进程内排查**
     - **极其困难，跨多个服务和网络**
   * - **可观测性需求**
     - **低：日志 + 简单监控即可**
     - **高：需要分布式追踪、度量、日志三位一体**

最后两行是关键——微服务让问题诊断的难度呈指数级增长。
一个请求可能经过 5-10 个服务，任何一个环节出问题都可能导致用户感知到异常。
而传统的"看日志"方式在分布式环境下几乎失效。

1.1.2 为什么微服务让问题诊断变得困难
--------------------------------------

微服务环境下的问题诊断面临三大挑战：

**1. 信息屏障**

每个服务是一个独立的进程，有自己的日志、自己的状态。
当问题发生时，你需要在多个服务的日志中拼凑出完整的故事。

**2. 网络不确定性**

服务之间通过网络通信，网络延迟、抖动、丢包都可能导致问题。
而这些问题往往是间歇性的，难以复现。

**3. 级联故障**

一个服务的延迟升高，可能导致调用它的服务超时，
进而引发连锁反应，最终整个系统雪崩。

.. code-block:: text

   用户请求 → API 网关 → 服务 A → 服务 B → 服务 C → 数据库
                                      ↓
                                   服务 D → 缓存
                                      ↓
                                   服务 E → 消息队列

   问题：用户感知到延迟升高。
   原因可能在上述任何一个环节。
   没有度量，你只能逐个排查。

这就是为什么微服务架构 **必须** 有完善的度量体系。
度量不是锦上添花，而是微服务能否在生产环境中可靠运行的 **必要条件**。


1.2 什么是度量驱动开发
========================

1.2.1 MDD 的定义
-----------------

度量驱动开发（Metrics Driven Development, MDD）是一种软件工程方法论，
其核心理念是：

   **在软件开发的全生命周期中，将度量作为一等公民。
   度量代码与业务代码同等重要，同步设计、同步开发、同步上线。**

MDD 不是简单的"加个监控"，而是一种思维方式的转变：

- **传统方式**：先写业务代码 → 上线 → 出问题 → 补监控
- **MDD 方式**：设计度量方案 → 业务代码 + 度量代码同步开发 → 上线即可观测

1.2.2 MDD vs 传统监控
-----------------------

.. list-table:: MDD vs 传统监控
   :header-rows: 1
   :widths: 25 35 40

   * - 维度
     - 传统监控
     - 度量驱动开发
   * - 时机
     - 事后补救
     - 事前设计
   * - 范围
     - 基础设施为主
     - 基础设施 + 应用 + 业务全覆盖
   * - 目的
     - 发现问题
     - 发现问题 + 指导决策 + 持续改进
   * - 责任人
     - 运维团队
     - 开发团队（Own your code on production）
   * - 与开发流程的关系
     - 独立于开发流程
     - 嵌入开发流程（PDCA 循环）

1.2.3 PDCA 循环在 MDD 中的应用
--------------------------------

MDD 遵循经典的 PDCA（Plan-Do-Check-Act）循环：

.. code-block:: text

   ┌─────────────────────────────────────────────┐
   │              MDD 的 PDCA 循环                 │
   │                                               │
   │   Plan（计划）          Do（执行）             │
   │   ┌──────────┐         ┌──────────┐          │
   │   │ 确定度量  │ ──────> │ 实现度量  │          │
   │   │ 目标和    │         │ 代码，    │          │
   │   │ 关键指标  │         │ 采集数据  │          │
   │   └──────────┘         └──────────┘          │
   │        ▲                     │                │
   │        │                     ▼                │
   │   ┌──────────┐         ┌──────────┐          │
   │   │ 基于数据  │ <────── │ 分析度量  │          │
   │   │ 采取行动  │         │ 数据，    │          │
   │   │ 持续改进  │         │ 发现问题  │          │
   │   └──────────┘         └──────────┘          │
   │   Act（行动）          Check（检查）           │
   └─────────────────────────────────────────────┘

每一次迭代都让系统的可观测性更加完善，
让团队对系统的理解更加深入。


1.3 AI 时代的服务架构演进
==========================

2023 年以来，AI 应用的兴起为服务架构带来了新的变化。
传统微服务主要处理确定性的业务逻辑，而 AI 应用引入了大量不确定性：

.. list-table:: 传统微服务 vs AI 应用服务
   :header-rows: 1
   :widths: 20 40 40

   * - 维度
     - 传统微服务
     - AI 应用服务
   * - 响应时间
     - 毫秒级，可预测
     - 秒级，随输入长度波动
   * - 成本模型
     - 按计算资源计费
     - 按 Token 计费，与输入输出长度相关
   * - 正确性
     - 确定性，可用单元测试验证
     - 概率性，需要统计评估
   * - 依赖
     - 内部服务 + 数据库
     - LLM API + 向量数据库 + 外部工具
   * - 扩展性
     - 水平扩展相对简单
     - 受限于 LLM API 速率限制和成本

**AI 应用的典型架构：**

.. code-block:: text

   ┌──────────────────────────────────────────────────────┐
   │                    AI 应用架构                        │
   │                                                       │
   │  ┌─────────┐   ┌──────────┐   ┌──────────────────┐  │
   │  │ Web/API │──>│ AI 网关   │──>│ LLM Provider     │  │
   │  │ Gateway │   │ (路由/    │   │ (OpenAI/Claude/  │  │
   │  │         │   │  限流/    │   │  本地模型)        │  │
   │  │         │   │  缓存)    │   │                  │  │
   │  └─────────┘   └──────────┘   └──────────────────┘  │
   │       │              │                                │
   │       │         ┌────┴────┐                           │
   │       │         │ RAG     │                           │
   │       │         │ Engine  │                           │
   │       │         └────┬────┘                           │
   │       │              │                                │
   │       │         ┌────┴────┐                           │
   │       │         │ Vector  │                           │
   │       │         │ DB      │                           │
   │       │         └─────────┘                           │
   │       │                                               │
   │  ┌────┴────────────────────────────────────────────┐  │
   │  │           传统微服务层                            │  │
   │  │  用户服务 │ 订单服务 │ 通知服务 │ ...            │  │
   │  └─────────────────────────────────────────────────┘  │
   └──────────────────────────────────────────────────────┘

这种架构下，度量的重要性更加突出：

- **LLM 调用成本不可控** —— 必须度量 Token 使用量和费用
- **响应质量不确定** —— 必须度量生成质量（幻觉率、相关性）
- **延迟波动大** —— 必须度量 TTFT、TPS 等 LLM 特有指标
- **Agent 行为不可预测** —— 必须度量工具调用准确率、循环检测

传统的度量体系（HTTP 状态码 + 响应时间）已经远远不够。
我们需要一套覆盖 **性能、成本、质量** 三个维度的全新度量体系。
本书第 9-11 章将详细介绍 AI 应用的度量方法。


1.4 度量驱动开发的全景图
==========================

1.4.1 MDD 方法论概览
---------------------

度量驱动开发贯穿软件开发的全生命周期：

.. code-block:: text

   ┌─────────────────────────────────────────────────────────┐
   │                MDD 全生命周期                             │
   │                                                          │
   │  需求分析        开发实现        测试验证        运维监控  │
   │  ┌──────┐       ┌──────┐       ┌──────┐       ┌──────┐  │
   │  │定义   │──────>│实现   │──────>│验证   │──────>│监控   │  │
   │  │SLI/SLO│       │度量   │       │度量   │       │分析   │  │
   │  │确定   │       │代码   │       │覆盖   │       │告警   │  │
   │  │关键   │       │埋点   │       │度     │       │优化   │  │
   │  │指标   │       │采集   │       │       │       │       │  │
   │  └──────┘       └──────┘       └──────┘       └──────┘  │
   │      │                                            │       │
   │      └────────────── 反馈循环 ─────────────────────┘       │
   └─────────────────────────────────────────────────────────┘

1.4.2 度量的三个层次
---------------------

度量体系分为三个层次，从下到上依次是：

.. list-table:: 度量的三个层次
   :header-rows: 1
   :widths: 20 30 50

   * - 层次
     - 关注点
     - 典型指标
   * - 基础设施层
     - 硬件和操作系统
     - CPU、内存、磁盘、网络、GPU
   * - 应用层
     - 服务性能和健康
     - TPS、响应时间、错误率、连接池
   * - 业务层
     - 业务目标和用户体验
     - DAU、转化率、APDEX、任务完成率

对于 AI 应用，还需要增加两个特有层次：

- **质量层**：LLM 输出的忠实度、相关性、幻觉率
- **成本层**：Token 使用量、API 调用费用、每查询成本

.. tip::

   度量的一个核心原则：**越往上越重要，越往下越容易量化。**
   基础设施层的 CPU 利用率很容易测量，但业务层的"用户是否满意"很难量化。
   好的度量体系需要从上到下全覆盖。

1.4.3 USED 框架
-----------------

本书提出 **USED 框架** 作为度量的核心维度：

- **U — Usage（使用量）**：系统被使用了多少？QPS、并发数、Token 消耗
- **S — Saturation（饱和度）**：系统还有多少余量？CPU 使用率、连接池占用率、队列深度
- **E — Error（错误）**：系统出了多少错？错误率、超时率、幻觉率
- **D — Delay（延迟）**：系统有多快？P50、P99 延迟、TTFT

USED 框架可以应用于任何层次的度量：

.. list-table:: USED 框架应用示例
   :header-rows: 1
   :widths: 15 22 22 22 22

   * - 层次
     - Usage
     - Saturation
     - Error
     - Delay
   * - 基础设施
     - 网络带宽
     - CPU 使用率
     - 磁盘错误
     - 磁盘 IO 延迟
   * - 应用
     - QPS
     - 连接池占用率
     - HTTP 5xx 率
     - P99 延迟
   * - LLM
     - Token 消耗量
     - API 速率限制
     - 幻觉率
     - TTFT

1.4.4 三大护法：TDD + MDD + 活文档
-------------------------------------

度量驱动开发不是孤立的，它与测试驱动开发（TDD）和活文档（Living Documentation）
共同构成 AI 时代软件质量的"三大护法"：

.. list-table::
   :header-rows: 1
   :widths: 20 25 25 30

   * - 护法
     - 核心问题
     - 实现方法
     - AI 时代的价值
   * - **可验证性**
     - 代码写对了吗？
     - TDD
     - 让 AI 先写测试，再写实现
   * - **可观测性**
     - 代码跑得好吗？
     - MDD
     - 上线即可观测，问题秒级定位
   * - **可理解性**
     - 人能看懂吗？
     - 活文档
     - 架构图、注释、运维手册自动生成

三者相互支撑：TDD 确保代码正确，MDD 确保运行健康，活文档确保团队理解。
缺少任何一个，系统都会在某个维度上失控。


1.5 土豆微服务案例
==================

本书以一个名为"土豆（Potato）"的微服务示例贯穿全书。
它是一个待办事项管理应用，被拆分为以下微服务：

.. list-table:: 土豆微服务
   :header-rows: 1
   :widths: 30 70

   * - 微服务名称
     - 职责
   * - potato-server
     - 提供待办事项的 CRUD API
   * - potato-scheduler
     - 定时检查并发送提醒通知
   * - potato-web
     - 提供 Web 前端界面

.. code-block:: text

   ┌─────────────┐    ┌──────────────────┐    ┌──────────────────┐
   │ potato-web  │───>│  potato-server   │<───│potato-scheduler  │
   │  (Web UI)   │    │   (REST API)     │    │  (定时任务)       │
   └─────────────┘    └──────────────────┘    └──────────────────┘
                              │
                              ▼
                        ┌──────────┐
                        │  MySQL   │
                        └──────────┘

.. code-block:: bash

   # 快速启动
   git clone https://github.com/walterfan/mdd.git
   cd mdd/potato
   docker-compose up -d

在后续章节中，我们将以这个案例为基础，逐步添加度量代码，
展示如何从零构建一个完整的度量体系。


.. admonition:: 💡 避坑指南：度量系统建设的 3 个常见误区
   :class: warning

   **误区 1：度量越多越好**

   有些团队一上来就定义了上百个指标，结果没人看、没人维护。
   正确做法：从 USED 框架的 4 个维度出发，每个服务先定义 5-10 个核心指标。

   **误区 2：只度量基础设施**

   CPU、内存、磁盘这些指标当然重要，但它们无法告诉你"用户体验好不好"。
   正确做法：从业务层往下设计度量，确保每个层次都有覆盖。

   **误区 3：度量代码是事后补的**

   "先上线，后面再加监控"——这是最常见的技术债。
   正确做法：度量代码和业务代码同步设计、同步开发、同步上线。


1.6 本章小结
============

.. note::

   **关键要点：**

   - 微服务架构让问题诊断的难度呈指数级增长，度量是必要条件而非锦上添花
   - MDD 的核心理念：度量代码与业务代码同等重要，遵循 PDCA 循环
   - AI 时代的服务架构引入了新的不确定性，需要覆盖性能、成本、质量三个维度
   - USED 框架（Usage/Saturation/Error/Delay）是度量的核心维度
   - TDD + MDD + 活文档构成 AI 时代软件质量的"三大护法"


.. admonition:: 📝 思考题

   1. 回顾你当前负责的系统，它的度量覆盖了 USED 框架的哪些维度？哪些维度是缺失的？
   2. 如果你的系统引入了 LLM 调用，你会增加哪些度量指标？
   3. 你的团队是"先上线后加监控"还是"度量代码同步开发"？如果是前者，你会如何推动改变？
