浅谈最前沿 运维22世纪真实链路式 监控报警 设计理念
                                                    51CTO 主讲老师:大米哥

本课程大纲概述

1: 通过真实案例 看清 不准确的监控报警带来危害
2: 详细分析 一个运维 在分析排查故障时候的过程细节 (同样基于真实案例)
3:运维真实链路式监控 的基本理念和思路
4: 本篇分享课程 总结篇 (给出大家一个 完整的框架图)


1: 通过真实案例 看清 不准确的监控报警带来危害

做过运维相关工作的朋友都知道一个词 , 7*24 也就是说 咱们当运维的 为了维护线上集群的稳定 维护企业产品的稳定
我们需要本着一个无时无刻 都监视着整个线上环境的稳定状况 这样一种精神, 这也几乎成为一个好运维的"基本素养"了

那么为了达到这样的目标 , 自然 一套完善的监控系统 就首当其冲的 成为运维工作之中的重中之重了

其实任何一位公司的员工的都明白这个道理, 作为一个当下的互联网企业, 无论其规模大小, 核心线上产品都是作为 一个企业的灵魂

而由企业 通过常年累月所积累下来的 用户群 以及 用户固定的线上流量 这都是最最宝贵的资源

再说的通俗点, 流量 日活 这些都是可以跟金钱 收益 直接划等号的

所以说 , 一旦 线上生产环境出现故障的时候, 所有用户都无法使用你的产品的时候, 这对企业来说 是最最最致命的

这可比开发人员 写错几行代码逻辑, 测试工程师 忘了测试某条功能 , 销售人员 丢掉几个客户 还要严重的多的多的多!!

不是大米哥在这儿危言耸听 , 很有可能半小时的P0故障 (P0 P1 P2 P3)能让整个企业大家伙半年的辛苦努力 付之东流

有一句话说的好,咱们运维也可以套用一下 : 叫 辛辛苦苦三十年, 一夜回到解放前

22世纪真实链路式监控 设计理念分析_第1张图片
接下来 大米挑出 之前惨痛的真实经历 再给大家举两个例子

真实案例一: 10年前 在某家跨国大型互联网业务托管公司(云计算平台) 大米哥那时候所在的运维团队 负责着国外 近7000+服务器(包括物理机和虚拟机和所有其他设备在内)

企业的业务非常的庞大, 通过租赁的形式 托管着全世界(主要集中在欧洲 和 北美) 大大小小200多个门户网站 有视频的 有音频的 有多媒体 有广告 有论坛 有游戏 有足球 还有×××等等繁多

有那么一天的夜里,突然整个团队的报警电话响起(记得应该是 春节后不久),这是P0级别的报警, 于是运维们全都爬起来处理故障

那一次的故障 所有人 都是先查看报警信息, 记得报警信息当时 最少在邮箱中 也有 近200多条!!
(在那个年代 运维技术还很落后原始, 且监控体系远远不及现在的完善 , 自然排查故障就更困难更费时 )

当时的故障原因很隐蔽 一个运维团队 当时花费了近60分钟 才最终确定了问题所在

故障虽然最终解决了, 但是发生故障的所在地 是在国外,正处于白天 客流高峰期, 最终造成的瞬时损失 以及后续的影响 按照合约 需要赔付给客户(按秒计费)近十几万美金! , 这占据了当时年度营业的近十分之一啊 (那时候的企业 尤其外企 对于服务保障 用户的利益 还是非常尊重重视的 所以 赔付的力度很大 这么多年过去了 回想起来 还是挺值得敬佩的)

真实案例二: 4年前 在一家网络游戏公司, 那时候 大米是作为 运维架构师 负责着整个集群的设计和维护 以及人员的管理

其实随着 很多年经验的累积, 在监控报警方面 通过运维工程师们 以及 运维开发的不断努力 已经进步了很多很多了

记得当时 监控报警系统 由专们的2个Devops 和 1个运维 一同协作搭建 , 按照报警级别, 报警种类 归纳分类 各种去重 各种自动化集成 确实跟10年前那会 不可同日而已了

不过 游戏公司 相比其他互联网公司 是有很大的不同, 主要是体现在 高强度的即时的用户服务上 即时即时 这个词可就要了命了

玩过游戏的朋友 都知道一个叫做副本的概念把?? 网游中的副本 在技术的角度上, 其实就是特殊开辟的一类进程 ,副本中的进程进行单独的数据结算,结合缓存技术(redis memcache magoDB ) 最后再汇总到玩家角色的数据中(mysql)

(补充知识 网络游戏 会大量使用 缓存的机制 主要是为了将频繁不断的 用户数据传输 加快速度 且 保证数据的不丢失)

但是 玩游戏的用户 都是很有情节的 任何一点点的 物品损失 都是不能容忍的 (丢掉一件心仪的装备,有时候可比丢了一打现金 还愤怒)

有一次 某一个区服所在的 物理服务器 出现了故障报警, 级别很高 (P1)

但是由于 监控系统已经比较完善了, 于是 运维们 仅仅在15分钟内 就通过相对准确一些的报警信息中 定位了故障所在 且解决了问题
当时是区服服务器的 几个副本进程出现了 OOM的状况,造成进程假死 , 运维人员 迅速把相关用户缓存数据导出,并成功恢复了玩家的数据 ,重启了进程恢复副本

其实 这已经是 速度很快的 问题排查+处理了, 但是当时 还是后续产生了 意想不到问题

虽然 玩家在副本过程中的数据没有损失,但是 由于往家数量多 15分钟内 先后进入副本的玩家 有400多人, 而副本进入的当日次数 是有限制的 ,且副本最终的获利 很多人也没有得到结算 这些玩家中
后来就有一些玩家 在各大论坛进行了严厉的投诉 甚至直接找上门来理论, 最后还是给公司的形象造成了不小的损失

后来运维们在总结的时候, 觉得还是监控报警不够100%的准确 和 即时, 如果 能把排查解决故障时间 缩短到 3-5分钟内, 那么损失就会小很多

2: 详细分析 一个运维 在分析排查故障时候的过程细节 (同样基于真实案例)

通过前面两个例子 我们看得出 在紧急状况之下, 监控和报警信息 是运维唯一能依赖的 抢救线上环境的最直接救命稻草

我们也可以看得出 , 由于报警信息的普遍不准确 给运维在排查故障的时候 带来了很多很多的麻烦 和 误导

接下来 我们再通过一个真实的案例 详细分析过程 来看下

晚上11点钟 监控系统报警了, 累了一天的运维工程师 刚想躺下休息会 , 结果就被吵起来了 ...
我的妈呀 公司的APP完全打不开了 这是P0级别的报警啊!(监控报警的最高级别)
于是乎 慌忙起身打开电脑,查看具体的报警信息, 发现 100多封的报警邮件/短信 都塞满了 , 于是开始排查问题
从报警邮件中开始过滤, 其中有 如下一些内容

用户QPS报警: 某某接口流量骤然下滑
HTTP返回码报警: 某某接口全都返回 5xx了(502 503)
CPU报警:某某集群中 CPU一路飙高 快无法响应了
内存报警:各种OOM了
硬盘报警:大量错误日志导致硬盘塞满 ,还有其他各种硬盘分区满报警
日志报警:这里的内容就更"丰富"了, 各种代码error/ warining
数据库报警:各种访问连接数飙升 过高资源使用
连接数报警:负载均衡 反向代理 代码集群 大量waiting_connections 少量出现半连接等等
各种缓存集群报警: 大量并发连接, 过高资源使用, 主从同步缓慢 内存占用严重 等等

于是 苦逼的运维工程师 开始旅行自己的"神圣职责"了, 救火啊 排错啊 赶快想办法恢复线上请求啊啊啊啊~~

运维一般的反应是(尤其是当前阶段)啊呀 系统全面瘫痪了,是不是遭到***啦??

于是赶快去看外层流量图(内部监控nagios prome zabbix , 监控宝), 奇怪了 不对啊, 最外层流量图显示 并没有看到 超大的并发链接数 或者新建连接数啊
云产品的安全防护 也没有报出 遭到某某种类(如 DDOS, CC)***啊 , 那可以确定 不是***了

那接下来看下 数据库吧, 因为根据以往的经验, 越是后端的集群 越容易导致问题的出现
看了一下,果然 数据库资源利用过高, 连接数过大,有慢查询的现象
把数据库重启一下 试试吧(运维最大的利器 ), 重启几次之后,连接数和资源降下去 但是又迅速飙升回来 感觉没啥作用 看来不是数据库的问题

那么会不会是人为因素呢? 比如 哪个不懂事的开发人员 偷摸的晚上加班 未经许可上线功能了?
于是 赶快去看 发布系统记录(持续集成), 结果 今晚并没有任何线上程序的更新
但是也有可能是 开发人员 没有严格走持续集成的发布流程 自己手动上线呢?(SUDO)
干脆 把代码回滚到昨天 试试看把 , 回滚之后,问题依然没有解决, 看来不是代码发布问题

那么有没有可能 是哪台做负载均衡的机器 挂了 导致请求失败堆积呢?
看了一下负载均衡的所有节点, 发现健康检查的记录是OK的,也没有出现任何脑裂之类的现象 看来问题也不在这儿

接下来看看硬盘使用状况吧, 哎呀 核心集群的PHP错误日志 (Nginx) 把分区写满了, 这肯定是根儿啊, 于是乎 运维很熟练的
把日志移走,重启了所有核心集群的服务, 哈哈 一下子服务从5xx的返回码, 又变回200了, 太高兴了 终于解决了问题
可是呢。。。。。好景不长 没过多长时间, 又开始报警了。。。。 运维彻底奔溃了

问题到底在哪里啊。。。 疑????? 这里有一条硬盘报警 看着特殊一些
是缓存集群分区满了。。 于是 赶快上去看 redis日志, 发现大量的 REDIS_ERR , RDB_failures, 终于终于找到问题的根儿了。

由于缓存集群硬盘满,造成redis的RDB同步失败, 进而变成只读不写的状况, 这种情况下 从库无法再被更新,于是乎 主程序由于后续无法在
缓存读到最新的信息,进而去访问关系数据库, 且量越来越大(),到最终 完全不走缓存 而关系数据库 在这种情况下 ,很快会被消耗殆尽 造成请求的返回缓慢 慢查询
接下来 主程序层由于动态请求 无法正常响应 而造成堆积 返回码大量非200请求, 各种错误日志大量产生 CPU标高 ,内存耗尽,用户QPS下降 等等

真的是一波三折啊...

监控报警

3:运维真实链路方式监控 的基本理念和思路

通过上面一小节 ,详细的剖析 运维通过 监控报警信息分析 故障原因的时候

我们看到了一个很严重 且普遍存在的问题

由于监控报警信息 的数量庞大 且定位问题作用过小, 给运维工程师排查紧急故障 造成了很大的不便 以及宝贵时间的浪费(这里是最好的体现 时间就是金钱)

如何大幅度的提高 报警准确性 目前是个大企业 面临的最急迫的问题 (其实 这已经不单单是运维面临的问题了)

相信所有的运维工程师们 都在期待着一款绝妙的 完美的 监控报警工具 能帮我们把问题彻底完美的解决

但是很遗憾 , 虽然现阶段 市面上的 各类 开源监控软件, 商业监控平台 不断的迭代出新, 不过 我很肯定的告诉大家 经过这么多年的实际检验
目前尚未有一款成型的监控产品 能真真正正的帮运维 帮企业 把监控报警做到咱们期望的 完美境界

不过呢, 在不久之前 出现了一个声音 一个口号 , 或者说是一种新式的监控理念出现了

这就是 我跟大家所要介绍的, 咱们的主题, 真实链路式监控 理念

其实这个理念 也并不是由大米哥(我本人)第一个提出的, 我也是在一次和面试官的交流过程中 听到过这个词汇
当时我很激动, 立刻去搜索相关的资料,但是很郁闷的是, 发现这个新式的监控理念 到现在也仅仅停留在 口号的阶段(或者说 稍有思路)
并没有真正的开始研究,更不要说实现在运维生产环境上了

虽然有些遗憾, 但是真实链路式监控 这个提法, 尤其是 "链路" 这两个字 给了大米很多的灵感
接下来 我结合自己运维11年的生涯 给大家讲一下 对于 真实链路式监控 的设计理念思路

理念一: 完整化终极监控采样采集

记得大米在之前推出的 prometheus监控课程中 也提到过 监控采集

22世纪真实链路式监控 设计理念分析_第2张图片

上面这张图 大家应该还有印象, 不管是对于什么监控, 即便是 未来的真实链路式监控 也一样离不开 监控采集

数据的采集 对监控系统来说 是一切的源头

不过 对于 真实链路式监控 在设计理念上, 对于采集的强度 就更胜一筹了

我们需要把几乎所有的跟监控相关的数据 都要采集到, 这说起来容易 但是真想实现 是异常的庞大 且有点不可想象

举个例子来说:

就拿Linux操作系统中的一项指标CPU来说吧, CPU在Linux内核功能的划分下 会呈现八种状态

分别叫做 用户态, 内核态, 空闲态, Nice态, IO等待,硬中断, 软中断,虚拟化

( CPU在Linux当中, 是以这八种状态 , 按照时间片使用分配时长的方式 通过累积 + 百分比瞬时计算 来呈现 CPU各种状态下的百分比的 )
22世纪真实链路式监控 设计理念分析
如上是 咱们最熟悉的 TOP命令输出

每一种状态的CPU 对于分析操作系统的性能指标 都十分重要 (在低端的运维技术层面中, 可能只关注 用户态 和 内核态)

那么 CPU还会划分出 每一个CPU核 , 整体监控完整CPU 很多时候不够细致, 每一单核的状态 有的时候 也会影响全局
(曾经遇到过 redis 单进程 跑满32核CPU其中的一核,虽然整体CPU监控体现很闲,但是这一个进程造成了无法响应,最终引起故障)

所以说, 我们简单的来算一笔帐 , 在我们的 真实链路式监控 监控采集理念下, 光是一个CPU项
就得有 1(一个完整CPU) 16(假设16核) 8(八态)* 100(假设集群就100台服务器) , 这就是 12800 个小监控项....

真实链路式监控 的第一个理念 就是对 监控数据采样的超高完整性要求, 不可以遗漏任何一个 在集群中 有可能造成影响的 指标
不过 我们也看到了, 完美这个词 光从量上 就已经很庞大 有一点让人望而却步

这还只是一个CPU, 还没提到 内存 硬盘 IO 日志,程序 数据库呢。。。。

理念二: 监控数据 灵活矢量化建设

大多数的监控工具/平台, 对于监控采样数据的 都是一种 "分而治之 各自为政" 的处理形式

举个例子来说吧 一般的监控 在数据采集之后, 根据工程师定义好的规则 (各种大于小于临界值) 然后产生监控输出信息 和 报警信息

22世纪真实链路式监控 设计理念分析_第3张图片

如上图所示, 每一项监控项目 都是分开采集 分开计算 分开显示和报警

我们的第二项 真实链路式监控 的设计理念 需要建立一种 完美的 监控数据 矢量化
什么意思呢?

就是让 所有采集过来的 一个一个的监控项目 不再是孤立的 不再是分开
且 让每一个子项 都变成可被其他子项 后者是整个监控系统 可识别 可调用的 状态 (区块链的理念 )
可以实现彼此的沟通(通信)

举个简单例子来说 我们要求 所有监控项 能呈现如下这样的状态

22世纪真实链路式监控 设计理念分析_第4张图片

理念三: 矢量化的监控项目 建立层级连带+责任追溯关系

这个第三个设计理念 有点不太好理解了, 听大米好好讲解哦

什么叫做 层级连带+责任追溯呢?

我们通过之前的第二小节课程 给大家讲的那个实际例子 还记得不?
22世纪真实链路式监控 设计理念分析

由于一个缓存上的硬盘分区满了, 引起 其他各个地方连带的问题和报警, 并最终导致了 致命的数据库瘫痪 引起P0级别的故障

其实从这个实例 我们看出, 一个问题的引起 会引发一种连带式的 或者说是 连锁反应

总结一下 是这样的顺序: 硬盘分区满 -> RDB同步失败 -> redis从库失效 -> 程序大量访问转向 -> 各处请求WAITING堆积 -> 数据库资源繁忙 -> 数据库挂点 -> 最终导致用户请求无法响应 QPS严重下滑 -> P0报警的产生

这样的 一种按照顺序 一步一步连带的发生故障,就叫做 层级连带

而我们在这个例子 不难发现, 不管这种故障连带有多少层, 其实都有一个问题的起点 那么按照责任制的划分 追溯到源头 其实它就是原因
这个才是关键!! (最左边的硬盘问题)
而且 运维在排查解决的时候, 由于监控系统无法完美的提供支持, 这种源头一般很难第一时间发现 (除非是一个公司的 一个老运维 面对同样发生的问题 有可能能意识到 但这不是我们所追求的目标, 毕竟企业是铁打的营盘 流水的兵, 不可能总是依赖老运维 也不可能总是侥幸心理 盼望着每次都是同一个原因造成问题)

那么对于 第三个设计理念, 我们需要 真实链路监控 能提供类似如下的功能

理念四: 左推式+上推式 +评估式 + 分布式 最终形成 真实链路式监控

这一小节中 我们需要为 真实链路式监控 再贡献四项 模糊一些的 但是很重要的 算法支持

那么接下来 分别介绍着几个词是什么意思

1) 什么叫左推式呢? 为了说明这个,需要先简单介绍一下 企业标准五层线上架构

22世纪真实链路式监控 设计理念分析_第5张图片
如上图所示,五层线上架构 是当下企业运维架构的一种标准, 线上指的是处理用户在线的请求
(不能说 100%所有企业都是完全按照这个架构走的, 但是当前互联网运维线上架构的基本形式 差不多都是这个模式)

其中可以看到 由左向右 流量的传递过程 以及每个层级涉及的技术 ,一直推到最右边的 关系型数据库层

那么结合这张架构图 , 我们可以解释一下 什么叫做 左推式了

意思就是说,随着流量由左向右 逐层深入, 越是靠右边的层级出现故障,那么它所引起的连锁反应越严重,也更可能带来全线的瘫痪

举个例子来说, 最左边的洪流层负载均衡假设Down了一个节点, 因为有HA的存在 会被快速转移, 充其量就是加重了一些 其他LB节点的负担而已, 倒并不至于影响全局

但是 如果是最右边的关系数据库down了一节点,且这个节点对应的库和表 在业务级别中很重要, 那么一定会引起全面的业务瘫痪 ,而且整个左边的集群都会被牵连进去

所以 对于真实链路式监控, 符合左推式的算法 , 就应该 具备这一种判断,看看报警项 是处于哪一个层级, 然后 加入类似Linux nice值的一种东东 ,对报警的严重性 加入综合判断

2) 接下来说一下 什么叫上推式

上推式解释起来 要容易的多

在企业整套架构当中, 其实还可以按照 类似于 OSI七层模型的方式 ,由上向下的分级

最下层 我们可以定义为 网络层
中间层 我们可以定义为 OS系统层
中上层 我们可以定义为 系统服务层(开源服务 FTP DNS NGINX)
最上层 我们可以定义为 应用程序层 (开发的事)

这种树形分层的模型, 是为了说明一个问题, 越靠下层出现故障,越有可能影响面越大

举个例子

互联网集群 ,网络其实是底层,随着云计算的出现,可能运维都不需要太关注了,但是一旦网络出现问题 , 比如整个IDC,或者整个云可用区网络出现瘫痪
连PING都不通了, 那什么也不用说了,其他的地方也不用排查了,这个问题 就一定是导致全部产品瘫痪的源头

最上层 是应用程序层, 程序出现了一些问题, 比如 刚刚上线的一项小功能, 无法正常使用了, 那么可能也只是影响了一小部分用户体验而已, 到不一定就会影响全局

所以说 这就是给大家的第二个 真实链路监控的 理念, 树形结构的 上推式算法

3) 接下来 咱们说一下 什么叫做评估式

评估式的意思是说, 在监控的过程中, 如果同时出现问题是处在同一个层级 (不管是按照 前面所说的 左右分, 还是上下分)

在同一层级中, 并行出现的问题, 也需要有不同的判断依据, 也要根据业务种类的不同 有所区分

举个例子来说 , 假设 都是在 系统层面中 同时出现了 CPU 和 内存的报警 , 这两项报警 都属于 上推式当中的 OS系统层

而CPU 和 内存 对于不同密集型的集群 它的分量是不一样的

比如 在PHP(核心代码层) 这一般情况下 属于 CPU密集型 ,所以CPU的比重要高于内存 (排除一些 PHP代码(也包括其他代码)例如分配变量的不健康 导致的内存溢出等极端例子, 总体来说 健康的代码 重于计算 而不是过度消耗内存)
又比如 在大数据集群中, 内存的比重 明显要高于CPU (大数据行业有这么一句话, 内存决定生死, CPU决定效率), 也就说 Hadoop 内存如果不够了,可能直接导致MR任务挂掉, 如果CPU不足呢? 可能仅仅是运行速度变慢了

通过上面的两个 例子, 我们可以看出 评估式算法 的重要性, 也就是说 同一类的 或者 同一层级的 报警项目, 根据不同的应用种类, 真实链路监控 需要具备 灵活评估判断的能力(说起来简单 实现起来很难)

4) 最后 再来说下 分布式

分布式这个词一出, 大家理解上应该不会有问题吧? 听得很多很多了

关于什么是分布式, 我这儿不再给大家啰嗦它的底层含义, 感兴趣的朋友 可以自行查阅资料 多的是

大米在这儿 只是介绍一下, 为什么需要 把分布式的用法 融入到 咱们的 真实链路监控当中

前面在理念一的时候, 就跟大家说过了, 仅仅是数据采集一项 在量级上 就是非常巨大的(12800)

所以说 可想而知 如果真的要搭建出 真实链路监控的 平台, 在数据存储上, 以及计算方式上 需要依赖分布式存储 和 分布式计算
(顺带一提的是, 现阶段 对于分布式存储和计算 支撑最好的 自然是各种Hadoop大数据生态圈(实时性 YarnHadoop+spark HBASE STORM) ,不过 时代和技术的变迁是很快的, 我们并不知道 当有一天 真实链路监控真的用在生产环境的时候, 分布式是否还是现在这个样子 这就不好说了)


总结篇:

通过上面三个小节 , 我给大家分享了 未来真实链路式监控 的一些设计理念

其中很多的理念 其实都是我个人根据十多年运维架构的经验 所提出的 并不是所谓的官方定义

其实时代在发展 运维技术 企业架构 也在不断的更新迭代,实事求是的说 有一部分提到的设计理念

有可能会随着时间的推移, 也需要进行改良 需要再提出更适合的思路和方法 这都是不可避免的

不过 作为一个老运维, 经过十多年运维生涯的风风雨雨 , 对于这种完美监控的诞生需求 是始终不会变的 也是不会错的

最后 我们把上面所有的 关于 真实链路监控的知识点 设计理念 综合放在一张图中 大家可以多多体会一下吧 ^_^