第1页
微博平台在大规模、高负载系 统中的典型问题
新浪微博 平台及⼤大数据部 秦迪 @蛋疼的axb
第2页
今天我们不讨论...
微博平台的架构演进 如何实现⼤大规模、⾼高负载系统 XX技术在⼤大规模、⾼高负载系统中的应⽤用
第3页
今天我们讨论...
服务⼜又出问题了 服务⼜又出啥问题了 这不是我要的⽣生活
第4页
今天我们讨论...
功能问题
运⾏行结果出错 服务不可⽤用
性能问题
吞吐量低 处理时间慢
第5页
今天我们讨论...
• 处理问题 • 排查问题 • 预防问题
功能问题
运⾏行结果出错 服务不可⽤用
性能问题
吞吐量低 处理时间慢
第6页
处理问题
第7页
问题发生的前五分钟…
第8页
直观的监控
• 数据
- 单页面展示 - 按业务纵向分类
• 对比
- 时间轴/历史数据
& &
第9页
更直观的监控
• 原始信息不直观
- 过滤无用信息 - 分维度聚合数据 - 实时计算、分析、统计数据
• 一眼看出异常
- 30分钟定位问题:不能接受 - 3分钟定位问题:勉强及格 - 30秒定位问题:好用的监控
第10页
快速恢复
• 快速回滚
- 通过docker打包应用和运行环境 - 上线调度系统实时调度
• 快速降级
- 业务系统中预埋开关:资源、功能、接口 - 与调度系统集成,1分钟降级
• 快速扩容
- 多个服务共享docker服务池 - 与调度系统集成,5分钟扩容
• 快速迁移
- 多机房方案 :WMB - 流量切换系统:跨机房切换流量
第11页
排查问题
第12页
为什么大规模、高负载系统问题不易排查
• 定位问题难
- 信息量大,位置分散,噪声多 - 问题难重现
• 分析原因难
- 量变到质变,有时常识不适用 - 问题往往牵扯多个领域
• 解决问题难
- 解决的不是根本问题 - 很可能引入新的问题
第13页
案例:春晚演练时发现某服务性能不达标
• 背景
- 压测方案:迁移机房流量 - 逐渐迁移流量的过程中,服务突然僵死 - 接口吞吐量低于理论值2-3倍
第14页
春晚压测案例:通过监控初步定位问题
• 监控提供的信息
- 问题发生时间 - 异常时的现象
• web服务响应时间明显下降 • 某业务rpc服务大量超时,处理队列堵塞 • 出现异常时rpc服务器的CPU idle普遍降
低至10% • 后端资源没有波动
QPS$
1:30%
1:35%
1:40%
1:45%
rpc接⼝口响应时间
第16页
查日志的几种维度
• 关键词
- uid、请求、 ip...
• 时间
- 系统崩溃、某个时间点做过变更…
• 级别
- 过滤没有价值的信息、不知道发生了什么,找找灵感...
第17页
更高效的查日志
• 日志要完整
- 业务日志:包含关键路径与异常 - 性能日志:性能统计与分步耗时 - 容器日志、系统日志也很重要
• gc log、/var/log
• 关键词
- 上下文:日志中自动打印RequestID, 业务代码无感知
- 级别:WARN/ERROR
• 集中检索
- ELK/agent - 图表展示 - 也要考虑成本
第18页
春晚压测案例:日志里的信息
• 按请求统计
- 某几个批量查询接口超时最严重
• 按时间统计
- mc client最先开始超时
• 按异常类型统计
- 全部是超时报错 - 没有功能性异常
MC slow count
第19页
现场
第20页
首先要找到现场
• 保留现场
- 摘除节点:不要重启! - 导出现场:gcore/jmap/tcpdump
• 还原现场
- 还原前端请求:TCPCopy - 还原后端异常:TouchStone
第21页
深入内部,多看少想
• 快照分析
- 功能:观察程序当前的状态 - 场景:程序当前处于整体异常状态 - 举例:gdb、Xmap、mat、jstack
• 调用分析
- 功能:观察调用链和局部变量 - 场景:请求出错、请求慢、偶发错误 - 举例:btrace、Xtrace
• 聚合分析
- 功能:按某些维度聚合和对比定量数据 - 场景:查找性能问题 - 举例:perf、Xstat、Xtop、sysdig
第22页
春晚压测案例:新的线索
• 重现现场
- 本地压测没有重现问题 - 通过tcp copy引流线上机,问题重现
• 瓶颈分析
- 通过jstack发现大量线程卡在nio的closeIntFD上 - 通过perf发现close系统调用消耗了大量cpu - 通过strace发现close的系统调用处理时间在1s左右
第24页
看源码
• 建议常备在手边的源码
- 公司内部所有项目的源码 - 项目中依赖库的源码
• spring、netty
- 架构中开源应用的源码
• nginx、tomcat
- 基础设施的源码
• jvm、kernel
• 更快的找到源码
- 代码全文检索
第25页
了解原理
• 高负载系统需要了解的那些事...
- 应用:web容器、网络框架 - 网络:tcp/ip协议 - kernel:内存管理、cpu调度、文件系统 - 性能:Numbers Everyone Should Know
• tips:当心常识陷阱
- 常识可以用来提出疑点 - 常识不能用来否定疑点
第26页
春晚压测案例:问题的原因
- close调用在做什么
• 分析业务代码,使用mc client跨服务器批量获取数据时都会创建一个 nio selector,查询后销毁
• 查看jdk源码,发现selector在关闭时底层调用了close()
- 为什么每秒X次close调用会使cpu达到瓶颈?
• 我们尝试从原理上解释,但没有成功……
- 为什么测试环境的机器没有触发cpu瓶颈?
• 用tcp copy压测测试机,问题没有重现 • 对比两台机器,发现内核版本不一致 • 通过压测发现旧版本内核在频繁关闭epoll descriptor时有性能问题
第27页
<=>
解决
第28页
less is more
• 解决和改进是两件事
• 用最小的改动解决问题
- 升级 < 改造 < 重做
我就改了⼀一⾏行代码啊?
第29页
春晚压测案例:解决问题
• 解决问题
- 最小改动解决问题:升级内核
• 还有频繁关闭epoll的问题呢?
- 优化mc client实现:性能测试提升20% - 后续逐步升级
第30页
验证
第31页
确保解决方案是可靠的
• 确保问题被修复
- 开发环境验证 - 测试环境验证 - 线上环境验证
• 确保没有引入新的问题
- 灰度上线,观察服务状态
• 功能无异常 • 性能未下降
第32页
小结:在大规模、高系统中排查问题
范围
成本
第33页
预防问题
第34页
预防问题:从设计上预防问题
• 高可用
- 防单点:机器、机房、服务 - 服务隔离:按相关性、按重要度 - 超时控制:手动/自动降级 - 冗余评估:日常30%-50%冗余度
• 易运维
- 可干预:提供更多干预手段 - 减少黑盒:暴露更多内部状态信息 - 抽象和通用性:工具和流程建设
第35页
预防问题:从实现上预防问题
• 可靠的代码
- 代码质量:单元测试&Code Review - 耦合方式:同步 / 异步 / 丢弃 - 异常处理的异常处理:不要让事情变得更糟
第36页
预防问题:拥抱故障
- Q:如何判断一个系统在大规模、高负载下是否可靠? - A:没有实际流量验证前一定不可靠,验证后也不一定是可靠的。
- Q:压测压出问题怎么办? - A:压测压不出问题怎么办?
- Q:处理预案是越多越好吗? - A:一个演练过的预案要好过十个没有演练过的预案。
- Q:我特别害怕自己做的系统出故障,怎么办? - A:微博平台欢迎你:)
第37页
我们希望...
服务出问题了 服务出啥问题了 ⼜又学到了新姿势
第38页
Q&A
秦迪 @蛋疼的axb #微博平台架构#