W7D6 学习手册 1.调用链总览2.企业模式3.学习模式4.单层路由 5.单层重试6.成本单点7.Docker8.Compose 9.环境隔离10.Secret11.健康检查12.交付清单 达标①达标②自测速记

FDE W7D6 学习手册 · 单一调用链设计与部署交付基础

W7 Day6 · B 级(部署交付核心)· 4h · 学完能讲清"为什么只用一层路由/重试/成本统计 + Docker 部署 AI 服务的关键点"

本日定位:W7 是"企业 AI 平台与部署交付"周。D5 讲了网关(LiteLLM),D6 讲"调用链怎么设计才不乱"和"Docker 部署 AI 服务怎么落地"。这是把前面的能力真正交付成可用系统的工程底座。
学完能回答:① 为什么只用一层路由、一层重试(避免两层重复/冲突/成本双计);② Docker 部署 AI 服务的关键点(镜像/隔离/Secret/Health/Readiness)。
候选人背景:36 岁,Java + 大数据 + 医疗保险。重点放在 Java 侧企业 AI 平台 的调用链设计与容器化交付,强调"交付可运维、可排障"。
使用方法:通读原理 → 重点看「工程含义」「面试话术」「易错点」→ 做自测清单 → 配合《FDE-W7D6-评测题.md》。选中不熟的词可标注(左下★重要 / 右下📌待查)。
📚 延伸资源:Spring AI 全套实战(B站 BV1GfyGBqEm6,Java 侧 AI 应用开发,非 OpenAI 官方);LiteLLM 官方文档 docs.litellm.ai

一、企业 AI 调用链总览:为什么需要"统一调用链"

1.1 问题来源

一个企业 AI 平台,调用会穿过多个组件:业务应用、应用框架(Spring AI)、网关(LiteLLM)、模型服务。每一层都可能"好心"地加上路由、重试、成本统计——结果就是重复做、互相冲突、账目混乱

1.2 核心原则

每一类职责(路由 / 重试 / 成本统计 / 超时)只允许在「一层」里做,且放在最该做的那层
对企业交付,调用链清晰 = 排障路径清晰。一个请求失败,你能立刻定位"是 Spring AI 超时、还是网关拒绝、还是模型 5xx"。如果每层都重试都路由,出了问题谁都讲不清是哪个环节,SRE 会崩溃。Java 候选人要把这点讲成"工程纪律"。
统一调用链的核心是"每类职责只在一层做"。路由/重试/成本/超时各归其位,排障路径才清晰。多层重复做会导致冲突和账目混乱,是交付大忌。
① "统一调用链"不是"把所有逻辑塞一层",而是分层各管一类职责。② 成本统计若两层都做,会 double count,账单翻倍,CFO 追杀。③ 多层重试会造成"重试风暴"——一层失败触发重试,另一层又重试,请求量指数放大。

二、企业模式:业务 → Spring AI → LiteLLM → 模型

2.1 调用链

业务应用(Java) ──▶ Spring AI ──▶ LiteLLM Proxy ──▶ 厂商/私有模型服务

2.2 各层职责(企业模式)

负责不负责
业务应用 / Spring AI业务编排、Prompt、工具调用、应用层超时厂商 Key、预算、多租户治理
LiteLLM Proxy路由、虚拟 Key、预算、配额、成本统计业务语义、Prompt 编排
模型服务推理治理(除非是私有自研模型侧自带)
企业模式把"治理"集中到网关,Spring AI 只做应用编排。好处:多业务系统共用一个网关,治理一致;换模型厂商业务零改动。Java 团队维护应用,平台团队维护网关,职责清晰。
企业模式:Java 业务经 Spring AI 调 LiteLLM 网关再调模型。治理(Key/预算/路由/成本)归网关,业务编排归 Spring AI。换厂商业务零改动。
① 企业模式前提是有网关;若没网关又想"企业级",Spring AI 就得多干治理的活,职责变重。② 两层都做成本统计是最常见的坑(Spring AI 也记、网关也记),必须只保留网关记。③ 应用层超时要设,但不能和网关超时叠成"双重超时导致提前断"——要协调。

三、学习/自研模式:业务 → 自研 Model Adapter → 模型

3.1 调用链

业务应用(Java) ──▶ 自研 Model Adapter ──▶ 厂商/私有模型服务

3.2 适用场景

对应 D4/D5 的"自研 Gateway"路线:公司没有/不用 LiteLLM,自己写一层 Model Adapter 统一各家调用、做简单路由与重试。常见于已有强 Java 治理体系、不愿引入 Python 组件的情况。

3.3 与企业的区别

两种模式本质都是"单一调用链",区别只在"网关是买的还是自研的"。无论哪种,路由/重试/成本仍只在一层做——自研模式里就在 Adapter 这一层做,别再在业务代码里又写一遍。
学习/自研模式是业务经自研 Model Adapter 调模型,治理在 Adapter 内。和企业模式区别只在网关是自研还是 LiteLLM,但"单一职责层"原则不变。
① 自研 Adapter 很容易"顺手"把重试、路由、成本全写进去还不规范,最后变成 D5 说的"LiteLLM 山寨版"。② 自研模式下更要警惕:业务代码里别再偷偷加一层重试,否则同样有重试风暴。③ Adapter 也要高可用(它是咽喉),别写成单点。

四、为什么只用一层路由(避免两层路由冲突)

4.1 两层路由的问题

若 Spring AI 业务侧做一层路由("这个请求走模型 A"),网关又做一层路由("这个 Key 走模型 B"),两者可能决策冲突或叠加

4.2 正确做法

路由依据放哪层
厂商/模型选择(按预算、白名单、成本)网关(LiteLLM)一层做
业务语义选择(如保单类型)在到达网关前由业务/薄路由层决定(选哪个虚拟 Key),进网关后不再二次路由
路由的"最终决策权"只能在一个地方。建议:业务层只决定"用哪个虚拟 Key/租户",真正的模型映射与预算路由全由网关做。这样业务简单、网关权威,不冲突。
两层路由会冲突/叠加、行为不可预测。正确做法:路由最终决策权只在一层(网关),业务层最多决定用哪个 Key,不二次路由。
① "业务选模型、网关又选模型"是典型反模式。② 若业务必须按语义选模型,应通过"选不同虚拟 Key"表达,而不是在网关外再建一套模型路由表。③ 两层路由冲突时,往往表现为"偶发走错模型",极难排查。

五、为什么只用一层重试(避免重试风暴与重复统计)

5.1 两层重试的灾难

Spring AI 重试 3 次、网关又重试 3 次 → 一次失败最多产生 3×3=9 次 实际请求。这叫重试放大 / 重试风暴

5.2 重试该放哪层

失败类型该哪层重试理由
网络抖动 / 网关 5xx / 超时靠近调用方的那一层(Spring AI 或网关二选一)瞬时错误,重试有用
业务错误(如结构化校验失败)应用层(带反馈重试,见 D2)需改 Prompt,网关不懂业务
预算/配额拒绝(429)不宜盲目重试应降级/排队,重试只会更快撞墙
重试的"总次数预算"要全局规划。经验:只在一层做网络级重试(如 Spring AI 设 maxAttempts=2),网关不再重试;或反过来网关做、应用不做。关键是不要两层都做。业务级(结构化校验)重试是另一类,单独在应用层做,不计入网络重试。
两层重试会放大成 N×M 次请求(重试风暴),压垮模型、翻倍成本、叠加延迟。正确:网络级重试只在一层做,业务级带反馈重试在应用层单独做,两类不混。
① 429(预算/限速)不要重试——只会更快撞墙,应降级或退避排队。② 网络重试和业务重试是两类,别把它们当成同一个"重试开关"乱开。③ 每层超时+每层重试会"双重等待",总延迟 = 超时×重试层数,要协调超时值。

六、成本统计只在一层做(避免 double count)

6.1 重复统计的后果

若 Spring AI 侧记录"本次花费"、网关(LiteLLM)也记录"本次花费",同一请求被记两次 → 成本报表翻倍,Chargeback 算错,业务线互相甩锅。

6.2 唯一可信来源

成本统计的唯一可信来源 = 网关(LiteLLM)落库(它掌握真实 token 用量与厂商计费)
金融客户对账单极其敏感。成本必须 single source of truth。交付时明确:网关是记账本,应用是流水账(仅调试用)。内部结算一律以网关 Spend 报表为准。
成本统计唯一可信来源是网关(它掌握真实 token 与单价)。应用层不要重复记账单,只记调试用 Trace。否则账单翻倍、结算混乱。
① "应用层也记一下成本方便看"是坑——记着记着就被当成结算依据,和网关对不上。② 网关成本依赖落库,库故障期间的成本会丢,要有补偿(如请求日志回算)。③ 项目标签伪造问题(D5)会让结算错,网关侧强制归属更可靠。

七、Docker 基础:AI 服务容器化

7.1 为什么用 Docker 部署 AI 服务

7.2 镜像要点(AI 场景)

关注点做法
基础镜像选带 CUDA 的(GPU 推理)或 slim 版(CPU/网关)
依赖Python 用 requirements 锁版本;Java 用多阶段构建减小体积
模型权重大模型权重不要打进镜像,用挂载卷/对象存储,镜像只放代码
非 root容器跑非 root 用户,降攻击面
AI 服务镜像和一般 Java 服务不同:模型权重动辄几 GB~几十 GB,绝不能打进镜像(镜像膨胀、拉取慢、难更新)。权重走 Volume/对象存储挂载,镜像只含运行时代码。这是交付时常犯的错。
Docker 给 AI 服务环境一致、隔离、可移植。AI 镜像要点:权重别打进镜像(走挂载)、非 root 运行、GPU 用 CUDA 基础镜像、依赖锁版本。
① 把模型权重打进镜像 = 镜像几十 GB、每次更新模型要重 build 重传,极度低效。② 容器默认 root 有安全风险,金融交付会卡合规。③ 镜像体积不控,K8s 拉镜像慢,发布变龟速。

八、Docker Compose 编排多服务

8.1 什么时候用

单机演示 / PoC / 小团队:用 docker-compose.yml 一把起"网关 + 数据库 + 业务"多个容器,定义网络和依赖顺序。

# 简化示例:网关 + 数据库
services:
  litellm:
    image: ghcr.io/berriai/litellm:main
    ports: ["4000:4000"]
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/litellm
    depends_on: [db]
    secrets: [litellm_master_key]
  db:
    image: postgres:16
    volumes: ["pgdata:/var/lib/postgresql/data"]
volumes: { pgdata: {} }

8.2 局限

Compose 适合单机,没有自动扩缩容、自愈、多节点。生产上这些交给 K8s(D7)。

交付节奏:先用 Compose 给客户快速演示"整套能跑",再上 K8s 做生产。Compose 是"验收演示利器",不是"生产方案"。要清楚边界,别把 Compose 当生产架构讲。
Compose 适合单机演示/小团队,一把起多容器、定依赖。但它无扩缩容/自愈/多节点,生产交给 K8s。是演示利器非生产方案。
① Compose 的 depends_on 只管启动顺序,不管"就绪"——DB 起了但没接受连接,网关可能连不上,要配合健康检查/重试。② 把 Compose 当生产架构讲,会被问"单节点挂了怎么办"。③ Compose 的 Secret 仍建议走外部 Secret 管理,别明文写 yml。

九、环境隔离(dev / staging / prod)

9.1 为什么隔离

开发、测试、生产必须隔离,否则:测试数据污染生产、实验性 Prompt 影响真实用户、密钥混用导致越权。

9.2 隔离维度

维度做法
网络/命名空间K8s namespace 或不同 VPC;dev/staging/prod 互不可达
配置各环境独立配置(模型地址、预算上限不同)
数据测试用脱敏/假数据,生产用真实(严格授权)
密钥各环境独立 Key,prod Key 仅 prod 可见
保险客户最忌"测试环境连了生产库"。交付时环境隔离是硬合规项:namespace 隔离 + 配置分离 + 数据脱敏 + 密钥分环境。staging 要尽可能"像生产"才能暴露真实问题。
环境隔离靠 namespace/网络隔离 + 配置分离 + 数据脱敏 + 密钥分环境。保险场景测试连生产库是严重事故,必须隔离。staging 尽量像生产。
① "staging 用生产数据方便测试"是违规高风险,金融必须脱敏。② 配置若共用一套,容易把 prod 的模型地址配到 staging,影响真实计费。③ 密钥跨环境复用 = 隔离形同虚设。

十、Secret 管理(API Key / 数据库密码)

10.1 原则

10.2 对比

方式风险
明文写在 yml/env提交到 Git 即泄露,灾难
K8s Secret(base64)仅是编码非加密,需配合 RBAC + 加密存储(etcd 加密)
Vault / 云 Secret Manager较优,有动态秘钥、审计、轮换
金融交付的 Secret 审计极严。厂商 Key 若明文进 Git,是 P0 事故。交付清单里必须有"Secret 不落代码、走 Vault/云、etcd 加密、有轮换流程"。这是 Java 候选人体现"交付成熟度"的点。
Secret 绝不进代码/镜像明文,走 K8s Secret/Vault/云 Secret Manager,最小权限 + 可轮换。K8s Secret 只是 base64 编码,需配 etcd 加密和 RBAC。
① K8s Secret 默认只是 base64,不是加密,谁有 get 权限就能解,必须开 etcd 加密 + RBAC。② "临时先明文,上线再改"基本永远不会改,要一开始就不明文。③ 密钥轮换流程缺失,泄露后只能紧急改代码重发,业务中断。

十一、Health Check 与 Readiness Check 的区别

11.1 两个探针

探针回答失败后果AI 场景例子
Liveness(存活)进程还活着吗重启容器进程卡死、死锁
Readiness(就绪)能接流量吗从负载均衡摘掉,不重启模型还没加载完、依赖的网关连不上

11.2 为什么 AI 服务特别要区分

很多团队把 Health 和 Readiness 混成一个接口,导致"模型没加载完就被打流量"或"依赖抖动就被杀容器"。AI 服务启动慢、依赖多,两个探针必须分开配,且阈值给足(模型加载慢)。
Liveness=进程活着否(失败重启);Readiness=能否接流量(失败摘流不重启)。AI 服务模型加载慢,进程活但没就绪,必须 Readiness=false 别接流量、别误重启。两探针分开配。
① 把 Readiness 失败当 Liveness 失败 → 容器被反复杀,模型永远加载不完(启动慢 + 被杀循环)。② 探针超时设太短,模型加载期间一直失败,误杀。③ 探针接口本身依赖外部(如查 DB),外部抖动会让探针失败、误摘流/误重启。

十二、AI 服务部署的工程交付 Checklist

12.1 上线前清单

这份清单就是"交付成熟度"的体检表。Java 候选人讲部署,不要只讲"docker run",要讲"我交付时会确保这 8 条都过关"。尤其调用链单一职责 + 降级 + 可观测,是区分"会跑"和"能运维"的关键。
交付清单:镜像规范、配置分离、Secret 管理、双探针、调用链单一职责、降级兜底、可观测串联、资源限配。八条全过才是"可运维交付"。
① "能 docker run 起来"≠"能交付"——缺降级和可观测,半夜出问题没人能查。② 调用链没做单一职责,上线后成本对账天天吵架。③ 资源不限(GPU/内存),一个请求 OOM 拖垮整节点,连带其他服务。

十三、面试达标线①:只用一层路由/重试/成本

职责只在哪层两层做的后果
路由网关(业务只选 Key)两层路由冲突、走错模型、难排查
网络重试一层(Spring AI 或网关二选一)重试风暴 N×M、压垮模型、成本翻倍
成本统计网关(唯一可信来源)账单 double count、结算混乱
核心:路由最终决策权在网关一层;网络级重试只在一层(业务级带反馈重试另算);成本以网关落库为唯一可信来源。每类职责单一归属,排障清晰、账目干净。

十四、面试达标线②:Docker 部署 AI 服务的关键点

镜像(权重外挂/非root/锁版本)→ 编排(Compose演示/K8s生产)→ 隔离(ns/配置/数据/密钥) → Secret(Vault/etcd加密/轮换)→ 探针(Liveness≠Readiness)→ 交付清单(降级/可观测/资源限)
  1. 镜像:模型权重走挂载不进镜像、非 root、依赖锁版本。
  2. 编排:Compose 做演示,K8s 做生产(扩缩容/自愈)。
  3. 隔离:dev/staging/prod 网络+配置+数据+密钥全隔离。
  4. Secret:不落代码,走 Vault/云,etcd 加密 + RBAC + 轮换。
  5. 探针:Liveness(重启)与 Readiness(摘流)分开,阈值适配模型加载。
  6. 降级/可观测/资源限:网关挂有兜底、Trace 串联、GPU/内存设限。

十五、W7D6 自测清单

十六、高频面试题速记卡

Q:为什么只用一层路由?
两层路由会冲突/叠加、走错模型、难排查。最终路由决策权只放网关,业务只选虚拟 Key。
Q:两层重试有什么灾难?
变成 N×M 次请求(重试风暴),压垮模型、成本翻倍、延迟叠加。网络重试只在一层做。
Q:业务级重试和网络重试是一回事吗?
不是。网络重试(超时/5xx)在一层做;业务级带反馈重试(结构化校验失败)在应用层另做,不混。
Q:429 该重试吗?
不该盲目重试,会更快撞墙。应降级或退避排队。
Q:成本统计为什么要只在网关做?
网关掌握真实 token 与单价,是唯一可信来源。应用再记会 double count,结算混乱。
Q:AI 服务 Docker 镜像最大的坑?
把模型权重打进镜像(几十 GB、难更新)。权重走挂载/对象存储,镜像只放代码。
Q:Compose 能当生产架构吗?
不能。它无扩缩容/自愈/多节点,只适合单机演示。生产上 K8s。
Q:Liveness 和 Readiness 区别?
Liveness=进程活否(失败重启);Readiness=能否接流量(失败摘流不重启)。AI 模型加载慢必须分开配。
Q:K8s Secret 安全吗?
默认只是 base64 编码非加密,需配 etcd 加密 + RBAC;更优是 Vault/云 Secret Manager。
Q:环境隔离为什么对保险客户重要?
防测试连生产库、实验 Prompt 影响真实用户、密钥混用越权——是硬合规项。
FDE W7D6 学习手册 · 单一调用链设计与部署交付基础(面试级)· 配合《FDE-W7D6-评测题.md》自测
📌 待查★ 重要