笃行
首页
个人 & 心法
互联网/硬件后台
游戏基础架构
UE 引擎
游戏业务
AI / 大模型
数据结构与算法
机器学习数学
通用基础
GitHub
首页
个人 & 心法
互联网/硬件后台
游戏基础架构
UE 引擎
游戏业务
AI / 大模型
数据结构与算法
机器学习数学
通用基础
GitHub
  • 接入与通信

    • 游戏基础架构与工具
    • 接入网关(长连接接入层)
    • 消息总线(共享内存 IPC)
    • 帧同步(Lockstep)
    • 全栈极限低延迟(物理层→应用层)
    • KCP 与 QUIC
  • 网络与服务网格

    • CNI 与 K8s 网络插件
    • 容器运行时:Docker 与 containerd
    • Istio 与 Cilium 服务网格
    • 服务网格:中心化 vs 去中心化
    • eBPF 原理与在网络/可观测/安全的落地
    • 自研 Mesh 服务网格 × K8s 部署
    • 自研 Mesh × K8s · 数据面深水区
    • Tco 协程框架 · 运行时深水区
    • K8s 异构 & 网络插件
  • 有状态服务

    • 分布式游戏存储(分布式 KV)
    • 有状态服务的数据迁移
    • 有状态服务的数据恢复与容灾
    • 有状态服务的 K8s 编排层治理(防漂移 + 节点崩溃恢复)
    • 内存配置热刷新与更新机制
  • 算法与协程

    • 一致性哈希四算法实现(Ring Hash / Ketama / Maglev / Jump Hash)
    • 蓄水池抽样(Reservoir Sampling)与加权扩展
    • C++ 协程:有栈 vs 无栈 vs C++20 原生(函数染色与 libco)
    • Raft 与 Gossip:CP 强一致共识 vs AP 最终一致传播
  • 流量与承载

    • 游戏秒杀场景承载
    • 令牌桶与漏桶
    • 限流与熔断
    • 限流:互联网 vs 游戏
    • 灰度发布 · Canary / BlueGreen / A-B / Shadow
    • 服务器日常系统开发与维护 SOP
    • 极限发压工具设计(多长连接 + 发压任务)
    • 性能分析与优化方法论(六条排查线)
  • 编译与排查

    • 编译优化与 LLVM/Clang/GCC
    • Sanitizer 工具链与内存泄漏定位

服务器日常系统开发与维护 SOP

发布/回滚 · 配置变更 · 日常巡检 · 值班响应 · 故障演练 · 变更评审 · 告警闭环——把发布策略、可观测性、容器运行时三块能力落到一张值班表里。

一句话结论

日常运维 = 把"发布策略 / 可观测性 / 容器运行时"三块单一事实源,装进一张七件套 SOP(发布/回滚 / 配置变更 / 日常巡检 / 值班响应 / 故障演练 / 变更评审 / 告警闭环)。每件套都要有入口条件 / 动作清单 / 成功指标 / 失败动作四段,靠 SOP 拉平人差,而不是靠个人英雄。

本篇的红线:不重复展开

  • 发布策略六模式与 K8s 五关键字段详见 release-strategy,本篇只讲"日常发布的动作清单"。
  • 可观测性三支柱与 P99 直方图/分位数陷阱详见 observability,本篇只讲"告警怎么落到值班"。
  • 容器运行时排障(containerd/CRI/OCI)详见 container-runtime,本篇只讲"排障入口"。

场景问题

游戏区服要 7×24 稳定跑,"日常维护"不是"没事就好",而是一整套值班动作:

  • 发版永远不空档:赛季更新、活动上线、hotfix 全挤在一起。上一次滚更是 3 小时前,下一次可能就在 20 分钟后。发出去、发不回、发一半都是常态。
  • 配置比代码变得更勤:新活动的开关、限流阈值、副本 buff 系数一天调好几次。配置变更没走灰度出事,回滚要比代码回滚更难(老版本不认新字段)。
  • 告警不是"看红点":凌晨三点手机响,你要 5 分钟内判定"这是重大故障还是抖动",10 分钟内决定"止损还是继续排查",30 分钟内出稳定结论。
  • 演练是必须:从来没演练过的恢复流程,真出事时几乎必然踩坑(详见 stateful-recovery 的"必须定期演练"警告)。

三个真实的日常事故

  1. 发布回滚拖尾:新版本推 25% 后 5xx 拉升,kubectl rollout undo 立即执行,但 Endpoints 摘除滞后 30s,客户端持续打到"僵尸 Pod"上——回滚动作做了 ≠ 流量真回滚了。
  2. 配置改错导致雪崩:把某活动的限流阈值从 5000 QPS 手动改到 500,忘了走灰度,全服瞬间打回 429,玩家投诉冲上话题榜——配置比代码更需要灰度。
  3. 告警疲劳:白天几百条告警没人看,凌晨一条真事故被淹没在"P99 抖动"和"磁盘 85%"里——告警设计不是加,是减。

发布、变更、告警不是彼此独立的操作,它们共同组成"日常 SOP"。这份 SOP 决定值班的人在事故来临前先做过多少次演练、事故来临时能不能按流程动作、事故过后能不能沉淀经验。

实现方案

七件套 SOP 全景

每件套按同一张卡片写清:入口条件 / 动作清单 / 成功指标 / 失败动作。

① 发布 / 回滚

段内容
入口条件变更单已过评审、灰度方案已定、回滚点已备份、值班已交接
动作清单1) 冒烟环境验一次;2) 按 release-strategy 的灰度 SOP 八步逐级放量;3) 每级观察 5–15 分钟指标;4) 达标自动进下一级,异常触发一键回滚
成功指标全量后 30 分钟内:错误率 < 基线 × 1.2、P99 < 基线 × 1.5、无 P0/P1 告警
失败动作立刻 rollout undo + 摘流量 + 拉 war-room + 通知值班群;回滚只算做完到"Endpoints 已摘",不算做到"命令返回成功"

回滚的两个反直觉

  • kubectl rollout undo 不等于流量已切回旧版:Endpoints 更新与 kube-proxy 生效有秒级延迟;对长连接服务,还要主动关连接触发客户端重连。
  • 有状态服务不能直接 undo:PVC 数据兼容性、消息 schema 兼容性都要提前双向兼容(详见 release-strategy 的 "DB Schema 双向兼容")。

② 配置变更

段内容
入口条件配置版本已在配置中心写好、灰度批次已划分、老配置作为回滚点保留
动作清单1) 单节点试灰度、观察 5 分钟;2) 单区试灰度、观察 15 分钟;3) 全服放量;4) 每步都在告警群 @ 值班
成功指标目标行为生效 + 无关指标不动
失败动作配置中心一键回滚到上一个版本号;若配置触发副作用(如 buff 系数已发放奖励)需走补偿而非"改回来"

配置变更三板斧:评审 / 灰度 / 回滚点——三样缺一,事故必到。

③ 日常巡检

分三级:每日 / 每周 / 每月。清单不长,但必须每次都走完:

级别清单项落到工具
每日错误率 & P99 与基线对比、容量水位(CPU/Mem/磁盘/连接数)、依赖健康(DB/Redis/MQ)、昨日告警复盘Grafana 首页 + 告警平台
每周慢查询 Top 20 & 治理进度、证书 30 天内到期、Pod 重启次数异常、备份可恢复性演练一次慢查询报表 + 证书扫描 + 备份 chaos
每月依赖升级评估、容量趋势外推 3 个月、故障演练 1 次、变更成功率复盘变更平台 + Chaos 平台

备份 ≠ 可恢复

"备份存在"和"备份能还原到可用状态"是两件事。每周至少做一次备份还原演练(详见 stateful-recovery 的"必须演练"警告)。没演练过的备份,故障时等于没备份。

④ 值班响应

告警 → 值班 → 处置的四段式:

段目标关键动作
Ack 认领让告警不飘告警群 @ 认领,避免无人响应
Mitigate 止损先止血再查因摘流量、限流、降级、切副本、回滚——先做能止损的,不追求先找到根因
Root Cause 定位找到唯一因果链顺着 observability 三支柱:Metrics 发现 → Trace 定位 → Log 抠细节
Post-Mortem 复盘沉淀经验事故报告 + 时间线 + 5 Why + 行动项到人;行动项进变更平台跟踪

告警分级(对齐值班响应时限):

级别定义响应时限处置权限
P0全服/大区不可用、核心业务停摆5 分钟 ack、10 分钟 mitigate值班直接决定摘流量/回滚
P1部分玩家受影响、SLO 破线15 分钟 ack、30 分钟 mitigate值班 + 二线
P2单点异常、指标波动1 小时 ack值班次日复盘
P3只需知晓、无需处置无每周批处理

跨团队协同:谁是主责

出事时会有 5 个人同时 @:客户端、运维、DBA、网络、你。每次事故必须先指定"值班总协调"(通常是发现方或最先受影响方),其他角色以"支线"参与。没有总协调 = 三个小时后大家还在各自群里对齐。

⑤ 故障演练

Chaos 演练类型清单,按爆炸半径从小到大:

类型演练动作期望恢复表现
进程 Killkill -9 一个 PodK8s 重启 + 长连接客户端自动重连
网络分区tc netem 加 100ms 抖动 / 20% 丢包限流不误伤、Retry 不雪崩
磁盘满提前灌满 /var/log日志切换到备用盘 / 熔断保护主进程
DNS 抖动屏蔽 DNS 服务器走本地缓存 / 长连接不受影响
依赖降级停掉某个下游熔断触发 / 回退到本地兜底
节点下线Cordon + DrainPod 迁走、有状态走 k8s-stateful-ops 的 NonGracefulShutdown 路径

演练前签发 + 止损策略:每次演练要有 announce → kick-off → observe → abort-condition → close-out 五步;abort-condition 命中立刻结束演练,不硬扛。

演练与真实事故的边界

  • 演练时的止损是预定义的、可控的;真实事故的止损是当场判断的。
  • 演练不能变成真实事故的替代品——只有真实事故的复盘才能让 SOP 长牙。
  • 演练不能只在测试环境做;关键的、可控的必须在生产做一次,否则等于没做(真实环境的量级和依赖没法在测试环境复刻)。

⑥ 变更评审

每一次变更(代码、配置、依赖、拓扑)走 CAB(Change Advisory Board)三步:

  1. 发起方自评:变更范围、影响面、回滚方案、灰度批次
  2. 同侪评审:架构点 / SRE / 值班三方 review
  3. 值班确认:值班日历不冲突(避免与大版本、赛季、大活动同期)

免审白名单要极窄:紧急 hotfix(P0/P1 事故下)+ 已模板化的配置项(比如某类活动的开关)。其余一律入审。

⑦ 告警闭环

告警设计三原则(对齐 observability):

  1. 可行动:每条告警必须对应一个明确动作。"P99 > 200ms" 不可行动;"P99 > 200ms 持续 5 分钟" + "预案:先看下游依赖,再看容量" 才可行动。
  2. 可分类:每条告警必须打 severity 标签(P0/P1/P2/P3),落到告警平台分级路由;P2/P3 不 wake 人。
  3. 不淹没:静默 / 去重 / 升级三件套——同类告警 15 分钟内静默、重复告警合并为一条、超时未 ack 自动升级到二线。

告警设计不是加,是减

告警平均每周新增 5 条却从不清理,一年后就是"告警垃圾场"。每季度做一次告警治理:命中率 < 10% 的告警必须要么调整阈值、要么下线。

为什么这么做

  • 为什么是"SOP"而不是"文档":日常运维的核心是拉平人差——不同人在同样场景下的动作差异必须收敛到几步内,否则事故只会发生在经验最少的那次值班上。SOP 不是给"看着办"留空间,是给"照着做"留台阶。
  • 为什么"发布 + 配置 + 变更"要合并成一条日常线:三者本质是同一件事的三种粒度(大版本 / 配置项 / 单参数),日常工作里它们互相耦合(配置依赖代码新字段、变更依赖发布节奏)。分开写就会出现"配置变了但代码没跟上"、"发布回了但配置没回"的对齐事故。
  • 为什么值班响应用四段式:Ack → Mitigate → RCA → Post-Mortem 是把"人的注意力"分配到最需要的阶段。先止血、后查因:查因是慢工,止血是分钟级动作,混淆两者 = 事故规模持续放大。
  • 为什么告警设计比告警本身重要:告警噪音本身就是事故——它让真事故没人看。所以告警设计的目标不是"告警越全越好",而是"告警到达时能被行动"。

为什么别的选择不行

  • "临时手工执行、不建 SOP":靠个人英雄主义撑值班表,一次交接、一次离职、一次深夜情绪化决策就把知识清空。
  • "发布就用 kubectl apply、不走灰度":单点回滚极慢、爆炸半径极大、无法量化验收。RollingUpdate 六模式对比与灰度八步存在的意义就是把"直接生效"这种最危险的动作从默认路径删掉。
  • "配置变更等同于代码变更、走一样的流程":配置变更的发生频率比代码高 10 倍,若走同样重的评审,运营节奏立刻卡死;若走同样轻的评审,事故立刻爆发。所以配置需要独立的三板斧(评审 / 灰度 / 回滚点)而不是共用代码 CI/CD。
  • "告警越多越安全":告警的边际效用递减——第 100 条告警的价值可能是负的(它让第 1 条告警被淹没)。减告警比加告警更工程化。
  • "演练只在测试环境做":测试环境的负载、依赖、数据量都与生产不同,测试环境的演练验证不出生产的失败模式。关键流程必须在生产做一次,且提前签发、随时可 abort。

三个绝对不做的动作

  1. 在没有回滚点的情况下变更:无论多小的变更。
  2. 不走灰度直接全量:无论多"简单"的配置。
  3. 发布 / 变更后立刻下班:至少留观察窗(15 分钟到 1 小时),把"我做完了" 变成 "指标验证了"。

沉淀结论

  • 日常运维 = 一份七件套 SOP(发布/回滚 / 配置变更 / 日常巡检 / 值班响应 / 故障演练 / 变更评审 / 告警闭环),每件套按"入口条件 / 动作清单 / 成功指标 / 失败动作"四段固化。
  • 发布策略、可观测性、容器运行时是三块能力,日常 SOP 是把它们装到值班表里的用法——本篇不讲原理,讲流程。
  • 三板斧铁律:评审 / 灰度 / 回滚点——变更任何东西都缺一不可。
  • 值班四段式:Ack → Mitigate → RCA → Post-Mortem——先止血、后查因,混淆两者事故就放大。
  • 告警设计三原则:可行动 / 可分类 / 不淹没——减告警比加告警更工程化。
  • 备份、演练、恢复三者都必须"做一次就是零、每周一次才叫有"——没演练过的能力不存在。

记忆口诀

七件套:发布/回滚 · 配置变更 · 日常巡检 · 值班响应 · 故障演练 · 变更评审 · 告警闭环
每件套四段:入口条件 / 动作清单 / 成功指标 / 失败动作
变更三板斧:评审 / 灰度 / 回滚点——缺一必炸
值班四段式:Ack 5m / Mitigate 10m / RCA 30m / Post-Mortem 3 天
告警三原则:可行动 / 可分类 / 不淹没——减告警而非加
巡检三级:日 = 指标水位依赖 / 周 = 慢查证书备份 / 月 = 依赖趋势演练
演练五步:announce / kick-off / observe / abort-condition / close-out
三不做:无回滚点变更 / 不灰度直接全量 / 变更后立刻下班

内容来源

综合整理。参考方向:Google SRE Book(值班、演练、告警设计章节)、Netflix Chaos Engineering、腾讯游戏后台运维实践、ITIL 变更管理框架、以及站内 release-strategy / observability / container-runtime / stateful-recovery 的日常应用视角。

自测:合上资料能说清楚吗?

Q1: "日常 SOP" 与 "发布策略" 是什么关系?为什么不合并到一篇?

发布策略讲的是六种模式的选型与技术细节(Recreate / RollingUpdate / BlueGreen / Canary / A-B / Shadow,五关键字段,Argo Rollouts / Flagger),是能力篇;日常 SOP 讲的是把能力装到值班表——什么时候用哪种模式、灰度批次怎么划、回滚窗口留多久、观察指标是哪些、失败动作是什么。两者的粒度和读者场景完全不同:一个是架构选型时读,一个是深夜值班时读。合并会让两个都读不下去。

Q2: 一条 P0 告警凌晨触发,你的前 15 分钟按什么顺序动?
  1. 0–1 min:Ack 认领(避免飘)+ 快速判定告警真伪(看关联指标是否同步异常)。
  2. 1–5 min:先做止损动作——最快的:摘流量 / 限流 / 降级 / 切副本 / 回滚。不追求先找到根因。
  3. 5–10 min:拉 war-room + 通知值班群 + 指定"值班总协调"。
  4. 10–15 min:顺 observability 三支柱开始 RCA:Metrics 报警面 → Trace 定位慢 span → Log 抠细节。
  5. 全程别忘:先做能止损的、再追求解释原因。
Q3: 一次赛季更新前的"变更评审"要卡哪几点?
  • 变更范围与影响面(哪些模块、哪些区服、多少玩家);
  • 灰度批次与放量节奏;
  • 回滚方案(回滚窗口、回滚点、回滚不可逆点);
  • DB Schema / 消息 schema 是否双向兼容;
  • 值班日历不冲突(不与大活动、其他大版本同期);
  • 依赖服务是否已被通知;
  • 告警是否已按新版本调整阈值。
Q4: 为什么"配置变更"不能走"和代码变更一样的流程"?

配置变更的频率是代码的 10 倍以上。若走一样重的评审 → 运营节奏卡死;走一样轻的评审 → 事故爆发。所以配置需要独立三板斧:评审(快速但必须走)、灰度(分批放量、观察窗)、回滚点(老配置版本号保留)。此外配置往往有副作用(比如已发放奖励),回滚不等于行为撤销,需要走补偿而不是"改回来"。

Q5: 告警"疲劳治理"具体做什么?
  • 每季度盘点:命中率 < 10% 的告警要么调整阈值、要么下线;
  • 告警必须有 severity 标签,P2/P3 不 wake 人;
  • 同类告警 15 分钟内静默、重复告警合并为一条、超时未 ack 自动升级;
  • 每条告警必须能对应一个明确动作(可行动原则);
  • 每条 P0/P1 告警必须有 runbook 链接指向操作手册。
最近更新: 2026/9/10 11:38
Prev
灰度发布 · Canary / BlueGreen / A-B / Shadow
Next
极限发压工具设计(多长连接 + 发压任务)