系统故障排查与性能优化实战:School of SRE 课程(Level 102)完整指南
教程【免费下载链接】school-of-sreAt LinkedIn, we are using this curriculum for onboarding our entry-level talents into the SRE role.项目地址https://gitcode.com/gh_mirrors/sc/school-of-sre点击查看免费下载本指南基于 School of SRE 课程level102/system_troubleshooting_and_performance整理面向以 Web API 服务为核心场景的 SRE 新人系统讲解故障排查的方法论、必备 Linux 工具、性能分析与基准测试手段并通过一个真实的 Python/Flask 内存泄漏排查案例演示问题复现 → 信息收集 → 定位根因 → 验证修复的完整闭环。读完本文你将掌握一套可复用的系统故障排查流程学会用top、sar、strace、lsof等命令快速定位问题并能借助tracemalloc、ab等工具对服务进行性能剖析与压测验证。课程定位与前置知识这是 School of SRE 课程体系位于 courses/level102/system_troubleshooting_and_performance/中面向初级 SRE 的入门课程。它尝试为以下场景提供通用性的故障排查入门指引分析 API 失败资源利用率问题CPU、内存、磁盘、网络网络问题硬件与操作系统问题通过性能剖析Profiling与基准测试Benchmarking衡量系统整体性能在开始本课程之前官方建议你先掌握以下 Level 101 的基础内容Linux 基础系统设计基础网络指标与监控本课程不涵盖的内容为避免范围失控本课程明确不涉及以下主题它们由课程体系中的其他部分承担系统设计与架构参见 systems_design 与 system_design编程实践参见 python_web指标与监控参见 metrics_and_monitoring操作系统基础参见 linux_basics为什么 SRE 必须掌握故障排查故障排查是运维与开发工作中最重要的组成部分之一但它无法通过阅读一篇文章或完成一门在线课程就能学会——它是一个持续的学习过程需要在以下场景中不断积累日常运维与开发发现并修复应用 Bug发现并修复系统与网络问题性能分析与优化排查问题前应具备的知识储备从 SRE 的视角出发要能够排查单机或分布式系统的问题你需要在平时就建立以下认知充分了解你的资源清楚主机的规格如 CPU、内存、网络、磁盘等。理解系统设计与架构只有知道系统如何组织才能判断故障出在哪一层。确保关键指标被正确采集与展示监控是排查的基础。HP 创始人有一句名言What gets measured gets fixed能被度量的就能被修复。如果系统组件与性能指标被完整地采集那么在问题发生的最早期成功排查的概率就会大大提高。这正是本课程把 指标与监控 列为前置课程的原因。课程范围界定不同类型的应用或服务没有统一的排查方法故障可能发生在服务的任意一层。本课程将范围聚焦于Web API 服务这一典型场景。说明Linux 生态非常庞大有成百上千种可用于系统故障排查的工具与实用程序每种工具都有各自的优势与功能。本课程只覆盖一部分知名工具要么 Linux 自带要么来自开源社区对工具的详细用法不做展开建议通过man手册页或在线资料深入学习。课程内容全景本课程共分五个部分每一部分都有独立的 Markdown 文档位于同一目录下可按顺序学习Introduction本页Troubleshooting故障排查方法论包含故障排查流程图、通用实践、通用主机问题Important tools to know必备工具重要 Linux 命令、日志分析工具Performance improvements性能改进性能分析命令、性能剖析工具、基准测试、扩展Troubleshooting Example排查实战示例内存泄漏排查全程演示Conclusion总结延伸阅读故障排查系统化方法论排查系统故障有时非常棘手和耗时。这项实践中我们需要检查一个服务的端到端流程所有下游依赖、日志分析、内存泄漏、CPU 占用、磁盘 IO、网络故障、主机问题等。掌握一定的实践与工具能更快地发现并缓解故障。故障排查流程图下面这张流程图原图见 TroubleshootingFlow.jpg是整个排查过程的高层指引它是一个典型的闭环流程流程从Start开始依次经历Reproduce Problem复现问题→ 2.Gather Information收集信息→ 3.Understand Problem理解问题→ 4.Find Solution找到解决方案→ 5.Apply Fix应用修复随后进入判断节点Fix working?修复是否生效若No回到Reproduce Problem重新排查若Yes进入Verify complete flow验证完整流程。最后再次判断Working?是否正常运行若No同样回到Reproduce Problem重新排查若Yes流程以End结束。这个闭环设计体现了排查的核心原则修复未生效或未达预期时必须回到起点重新复现与定位而不是在错误的方向上继续深挖。通用实践五步定位 Web 应用故障不同系统需要不同的排查方法。以下五个高层实践点针对寻找 Web 应用故障并找到修复方案这一目标展开1. 复现问题Reproduce problem尝试复现失败的请求例如重放失败的 http/https 请求检查请求的端到端流程关注返回码3xx多为重定向4xx多为未授权、错误请求、禁止访问等客户端问题5xx多为服务端问题。根据返回码决定下一步排查方向客户端侧的问题主要是静态内容缺失或存在 Bug例如 JavaScript 脚本错误、损坏的图片、异步调用返回的损坏 JSON 等这些会导致浏览器页面渲染不正确。2. 收集信息Gather Information在应用日志中查找错误/异常例如 Cant Allocate Memory、OutOfMemoryError、disk I/O error、DNS 解析错误等检查应用与主机指标寻找服务与主机图表中的异常CPU 使用率从何时开始升高、内存使用率从何时开始升高、磁盘空间从何时开始减少、磁盘 IO 从何时开始增加、负载均值load average从何时开始飙升等。监控相关的细节可参考 指标与监控查找近期可能破坏系统的代码或配置变更。3. 理解问题Understand the problem尝试将收集到的数据与近期操作关联起来例如配置/代码部署后日志中出现异常判断根因是因为 QPS每秒查询数上升是糟糕的 SQL 查询还是最近的代码变更要求更好或更多的硬件4. 找到解决方案并应用修复Find a solution and apply a fix基于以上发现尽可能寻找快速修复方案例如当错误/异常与变更相关时直接回滚Rollback如果想向前修复Fix forward尝试在预发布Staging环境打补丁或热修复Hotfix如果高 QPS 是系统失败的原因尝试纵向扩容按需增加资源计算、存储、内存等必要时优化 SQL 查询。5. 验证完整请求流程Verify complete request flow再次发起请求确保返回成功返回码2xx检查日志确保不再出现此前发现的异常/错误确保指标恢复正常。通用主机问题排查要判断主机健康状况是否正常排查硬件故障或性能问题可以尝试以下手段手段用途dmesg显示内核近期抛出的错误/故障有助于发现硬件故障lspci/lsblk/lscpu/lsscsi分别列出 PCI 设备、磁盘块设备、CPU 信息、SCSI 设备/var/log/messages显示系统应用/服务相关的错误与警告也包含内核问题smartd检查磁盘健康状态必备工具常用 Linux 命令与日志分析平台掌握以下命令能帮助你更快地定位问题各命令的详细用法请查阅man手册页场景命令日志解析grep、sed、awk、cut、tail、head网络检查nc、netstat、traceroute/6、mtr、ping/6、route、tcpdump、ss、ipDNSdig、host、nslookup系统调用跟踪strace多主机并行执行GNUparallel、xargssshHTTP/S 检查curl、wget列出打开的文件lsof修改系统内核属性sysctl分布式系统下的批量执行工具在分布式系统中一些优秀的第三方工具可以帮助你在大量主机上同时执行命令/指令基于 SSH 的工具ClusterSSH可以在多台主机上并行运行同一条命令Ansible编写 Ansible playbook可在成百上千台主机上同时执行。基于 Agent 的工具SaltStack配置、状态与远程执行框架提供了丰富的灵活性可在大规模主机上执行模块Puppet面向 Linux、Unix、Windows 系统的自动化管理引擎执行各类管理任务。日志分析工具这类工具支持用类 SQL 查询来解析和分析日志并提供易用的 UI 界面来创建基于查询渲染各种图表的仪表盘ELKElasticsearch、Logstash、Kibana提供解析日志、索引日志、分析日志的完整工具包。日志经 Logstash 解析/过滤并索引到 Elasticsearch 后几分钟内即可在 Kibana 中创建动态仪表盘从而方便地对应用错误/异常/警告进行分析与关联Azure KustoAzure Data Explorer与 Elasticsearch Kibana 类似的云服务支持对海量日志进行索引提供类 SQL 查询接口和动态仪表盘创建界面。性能改进分析、剖析、基准测试与扩展性能工具是开发/运维生命周期中重要的一部分对理解应用行为至关重要。SRE 通常使用这些工具评估服务将如何表现并据此做出/提出改进建议。性能分析命令以下命令是做系统或服务性能分析时的必知命令命令用途top实时查看运行系统、进程、线程等htop类似top但更具交互性iotop交互式磁盘 I/O 监控工具vmstat虚拟内存统计探查工具iostat设备和分区的输入/输出统计监控free显示物理内存与交换内存信息sar系统活动报告报告 CPU、磁盘、内存、网络等多种指标mpstat显示 CPU 利用率与性能信息lsof提供打开文件列表及其所属进程信息perf性能分析工具性能剖析Profiling工具剖析是服务性能分析的重要部分。多种剖析器可帮你找出最高频的代码路径hot code-paths、进行调试、内存剖析等还能生成热力图heatmap来理解服务在负载下的代码性能FlameGraph火焰图被剖析软件的图形化可视化工具可快速准确地识别最高频代码路径Valgrind用于内存调试、内存泄漏检测与剖析的编程工具GprofGNU profiler混合使用插桩instrumentation与采样sampling的剖析工具——插桩用于收集函数调用信息采样用于收集运行时剖析信息。工程实践参考LinkedIn 曾在其工程博客中介绍ODPOn-Demand Service Profiling按需服务剖析基础设施展示了在大型分布式系统中按需对线上服务进行剖析的实践思路。基准测试Benchmarking基准测试是衡量服务最佳性能的过程例如服务能承受多高的 QPS、负载上升时的延迟表现、主机资源利用率、load average 等。回归测试即负载测试在服务部署到生产环境之前是必须执行的。常用工具工具说明abApache Benchmark Tool对 Web 应用模拟高负载并收集数据用于分析httperf按指定速率向 Web 服务器发送请求并收集统计信息可逐步加压直至找到饱和点Apache JMeter流行的开源 Web 应用性能测量工具基于 Java不仅可用于 Web 服务器还可用于 PHP、Java、REST 等wrk现代性能测量工具可对 Web 服务器施压并输出延迟、每秒请求数、每秒传输量等指标Locust易用、可脚本化、可扩展的性能测试工具局限性以上工具属于合成负载Synthetic Load或压力测试它们无法测量真实终端用户体验——无法感知终端用户因内存、CPU 不足或互联网连接质量差而对应用性能产生的影响。工程实践参考LinkedIn 工程博客曾介绍如何在整支舰队fleet范围内做全自动负载测试以消除 toil以及如何利用RUMReal User Monitoring真实用户监控数据可视化来弥补负载测试的上述局限、改善终端用户体验。扩展Scaling一个设计良好的系统其性能上限也受限于可用资源。持续优化始终是保证资源在峰值期得到最优利用的必要手段。随着 QPS 的增长系统需要扩容方式主要有两种纵向扩展Vertical增加 CPU、内存、磁盘、GPU 等规格但存在物理上限横向扩展Horizontal受限于应用设计与环境属性但原则上可以近乎无限地扩展。扩展一个 Web 应用通常需要以下一项或多项操作增加更多主机以分担服务器负载使用负载均衡器Load Balancer在服务器之间分发流量通过数据分片Sharding和增加只读副本Read Replicas来扩展数据库。工程实践参考LinkedIn 工程博客的《A Brief History of Scaling LinkedIn》一文详细介绍了 LinkedIn 应用栈的演进式扩展历史是理解大规模扩展挑战的经典读物。实战示例用 tracemalloc 定位 Python/Flask 内存泄漏这一节演示一个真实可操作的案例一个带有内存泄漏 Bug 的 Flask Web 应用每次请求内存都会持续增长我们将使用 Python 内置的tracemalloc模块定位泄漏源头。内存泄漏问题往往在服务运行数天、数周甚至数月后、直到服务变得无响应才被发现除非重启服务或修复 Bug。这类服务的指标图会呈现持续上升的曲线如下图所示原图见 MemUsageChart.png内存泄漏本质上是应用对内存分配的管理失误不再需要的内存没有被释放随时间推移对象不断堆积最终导致服务崩溃。通常情况下这类未释放的对象会被垃圾回收器Garbage Collector自动回收但有时由于 Bug回收失败。调试可以帮助弄清应用存储内存主要被用在哪里然后你就可以基于使用情况跟踪并过滤一切对象如果发现某些对象未被使用但仍有引用就可以通过删除它们来避免内存泄漏。对于 Python 应用内置的tracemalloc模块可以帮助精确定位对象首次被分配的位置。几乎每种语言都有内置或外部的工具/库来帮助发现内存问题例如 Java 生态中著名的内存泄漏检测工具 Java VisualVM。步骤 1准备带 Bug 的 Flask 应用假设已经创建 Python 虚拟环境并在其中安装了 Flask。示例包含两个 Python 文件代码截图见 FlaskCode.pngapp.pyFlask 主文件一个存在内存泄漏 Bug 的最小应用from flask import Flask from fetchuserdata import user_data users_list [] # 用于累积用户数据的列表泄漏载体 # buggy_list [] # 注释说明此列表并非泄漏载体 app Flask(__name__) app.route(/) def index(): if user_data(users_list): # 每次请求都会向 users_list 追加数据 return fTotal users found {len(users_list)} return Failed to get user data if __name__ __main__: app.run()fetchuserdata.py数据模块def user_data(users_list): # 从数据库拉取用户数据并存入传入的列表 data [(Foo, Bar, 0123456789) for _ in range(5000)] # 每次调用构造 5000 条模拟数据 users_list.extend(data) # 内存泄漏根源列表不断累积数据直至耗尽内存 return True关键点在于users_list.extend(data)这一行它作为模块级全局变量在app.py中被反复传入并扩展每次 GET 请求都会向列表中追加 5000 条元组而这些数据从未被清理。步骤 2启动应用并观察内存增长在虚拟环境中启动应用启动输出见 FlaskStart.png(flaskapp) [user1user1 flaskapp]$ flask run启动后应用监听在http://127.0.0.1:5000/。此时用ps观察进程内存见 MemUsage01.png$ ps auxwh | grep [f]lask初始内存约为26576 KB约 26 MB。步骤 3逐次请求观察内存缓慢攀升每次发起 GET 请求进程内存都会缓慢但持续地增长见 MemUsage02.png四次请求后的表现请求次数响应内容进程内存第 1 次Total users found 500026948 KB较初始 372 KB第 2 次Total users found 1000027076 KB128 KB第 3 次Total users found 1500027120 KB44 KB第 4 次Total users found 2000027160 KB40 KB内存只增不减且响应中的用户总数在持续累加——这是列表在全局范围内不断扩展的直接证据。步骤 4用 ab 加压 10000 次请求验证为了确认泄漏规模使用 Apache 基准测试工具ab发起 10000 次请求$ ab -n 10000 -c 10 http://127.0.0.1:5000/压测完成后再次查看进程内存见 MemUsage03.png$ ps auxwh | grep [f]lask此时 Flask 进程内存已从初始的26576 KB 暴涨到 419316 KB——从约 26 MB 跳到约419 MB几乎增长15 倍。对于一个如此小的 Web 应用这是非常惊人的内存增幅明确证实了泄漏。步骤 5接入 tracemalloc 定位泄漏源头tracemalloc模块可在特定时间点抓取内存快照并对快照执行各种统计。在app.py中增加最小代码fetchuserdata.py无需改动新增一个/capture路由用于在访问时抓取 tracemalloc 快照import tracemalloc from flask import Flask from fetchuserdata import user_data users_list [] app Flask(__name__) tracemalloc.start() # 启动内存跟踪 app.route(/) def index(): if user_data(users_list): return fTotal users found {len(users_list)} return Failed to get user data app.route(/capture) def capture(): snapshot tracemalloc.take_snapshot() # 抓取当前内存快照 top_stats snapshot.statistics(lineno) # 按行号统计 result [] for stat in top_stats[:10]: result.append(f{stat.traceback}: {stat.size / 1024 / 1024:.1f} MB) return br.join(result) if __name__ __main__: app.run()注截图版示例代码位于 Tracemalloc01.png此处为便于阅读整理的等价实现核心思路一致——在快照后对分配对象按文件行号lineno分组统计。重启app.pyflask run后按以下顺序操作先访问http://127.0.0.1:5000/capture记录基线快照再访问http://127.0.0.1:5000/共 10000 次让内存泄漏充分发生最后再次访问http://127.0.0.1:5000/capture抓取第二次快照。对比两次快照见 Tracemalloc02.png 与 Tracemalloc03.png最终快照会精确指出内存分配量最大的模块与行号fetchuserdata.py的第 6 行即users_list.extend(data)在 10000 次请求后持有了约419 MB的内存。排查结论与生产环境注意事项以上示例展示了一个 Bug 如何导致内存泄漏以及如何借助tracemalloc定位其源头。真实世界的应用远比这个示例复杂请注意使用tracemalloc会因自身开销而在一定程度上降低应用性能在生产环境中使用需谨慎建议仅在调试窗口期开启或优先在预发布环境复现排查。对于 Python 对象内存分配内部机制与内存泄漏调试的深入探讨可参考 PyCon India 2019 的相关技术分享《Debug Memory Leak In Python Flask | Python Object Memory Allocation Internals》。总结复杂系统有太多可能出错的环节糟糕的设计与架构、管理不善的代码、不合理的缓存策略、糟糕的数据库查询或架构、不恰当的资源使用、不合适的 OS 版本、监控不到位的系统、数据中心问题、网络故障等——任何一项都可能引发故障。作为 SRE掌握关键工具与命令、最佳实践、性能剖析、基准测试与扩展手段将帮助你更快地完成故障排查与整体系统的性能改进。本课程的 Conclusion 中还列出了 LinkedIn 工程博客上的经典实战文章作为延伸阅读主题包括用 Jemalloc 驯服 Venice 中的内存碎片修复 Linux 文件系统性能回归慢速 NFS 对数据系统的影响运维中的每天都是星期一精神这些来自一线 SRE 的实战记录与本文的方法论和示例相互印证值得在完成本课程后逐一精读。课程学习路径建议Level 101 前置Linux 基础 → 系统设计 → 基础网络 → 指标与监控本课程正文Troubleshooting → Important tools → Performance improvements → Troubleshooting Example → Conclusion。建议在学习本课程时动手在你的实验环境里复现内存泄漏示例亲手运行ab压测与tracemalloc快照把方法论转化为可迁移的排查直觉。赞分享教程【免费下载链接】school-of-sreAt LinkedIn, we are using this curriculum for onboarding our entry-level talents into the SRE role.项目地址https://gitcode.com/gh_mirrors/sc/school-of-sre点击查看免费下载相关推荐KMSPico-2026用户常见问题解答解决激活失败、安全警告等10大难题KMSPico 2026用户常见问题解答解决激活失败、安全警告等10大难题 KMSPico 2026是一款专业的Windows激活工具能够为Windows如何用RWKV模型轻松创作高质量中文小说AI-Writer实用指南如何用RWKV模型轻松创作高质量中文小说AI Writer实用指南 想要体验AI智能写作的魅力吗AI Writer是一个基于创新RWKV架构的中文预训练生成AI 应用大模型AI 写作NLP本地部署掌握TCPdump与WiresharkSRE必备的网络故障排查终极指南掌握TCPdump与WiresharkSRE必备的网络故障排查终极指南 在软件可靠性工程SRE领域网络故障排查是确保系统稳定运行的关键技能。school教程上一篇Redux 设计溯源从 Flux、Elm、Immutable 到 RxJS 的前人艺术全解析下一篇如何3步解锁网易云音乐NCM文件Windows图形界面终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考