SRE(Site Reliability Engineering)是 Google 于 2003 年提出的概念,将软件研发引入运维工作。现在渐渐已经成为各大互联网公司技术团队的标配。 美团点评作为综合性多业务的互联网 + 生活服务平台,覆盖“吃住行游购娱”各个领域,SRE 就会面临一些特殊的挑战。 根据上述挑战,我们需要制定相应的解决策略,策略原则主要聚焦在以下三点: 在此原则的基础上,我们开始了对 SRE 进行的一系列改进。 SRE 演进之路 手工时代 最早期,我们前端是 4 层负载均衡,静态资源通过 Varnish/Squid 缓存,动态请求跑在 LAMP 架构下。这个时候机器很少,需要的流程很少,也没有区分应用运维、系统运维之类的。运维人员也很少,网络、机器和服务都要负责。运维的工作大部分都是靠手工,其实当时还没有成型的运维系统,现在很多初创公司都是这种架构。 云基础设施 随着业务的发展,我们的架构也做出了适当的调整。尤其是在步入移动时代以后,移动的流量比重越来越大。接入层不只是 Web 资源,还包含了很多 API 接口的服务。后端的开发语言也不再局限于 PHP,根据服务需求引入了 Java、Python、C++ 等,整个业务架构开始向微服务化变迁。伴随业务架构的变化,底层的基础架构也随之改变。最大的变化是,2014 年中的时候,所有的业务已经都跑在了云上,如下图所示。 跑在云上的一个好处是把底层主机和网络抽象化,相当于云平台将主机创建、网络策略修改等封装到相应的系统内,对用户提供统一的平台接口。我们在做维护的时候,就能把之前很复杂的流程串连起来。也是在此时,SRE 团队初步成立,我们对整个运维相关的工作做了拆分。云计算部分(由美团云负责)主要负责主机、网络,还有系统相关的;SRE 对接业务侧,负责机器的环境、业务侧的架构优化以及业务侧相关问题的处理。 接下来介绍一下我们在做云基础建设的过程中,遇到的问题和一些解决方案。 如上图所示,首先是资源隔离的问题,因为这个问题,造成过几次故障。我们线上 VM 的 CPU、网卡都是共享的,有一次,压测的流量很高,把主机网卡的带宽基本上都占光了(当时的主机大部分都是千兆的,很容易打满),同宿主机的资源都被它争抢了,其它 VM 上部署的服务的响时间变得很大,导致当时我们买单的一个服务(买单的 VM 和压测的 VM 部署在了同一个宿主上)直接挂掉了。 针对这个问题,我们做了两点,一个是对所有的网络资源都做了隔离,针对每个 VM 作相应的配额,另外一个是针对业务特性将宿主集群做了拆分。离线业务,它不考虑 CPU 的竞争,各个业务对于所部署服务的具体响应时间不是很关注,只要能在一个允许的时间段内把业务跑完就可以了,我们把这些服务单独的放在了一个离线集群。在线业务,根据不同业务的重要程度,又划分成了多个小集群。 第二个问题就是 VM 打散,这个问题初期的时候 得并不是很明显,当时整个线上的业务还没有做细致的服务化拆分,服务都部署在一个大集群内,这种情况下即使 VM 没有打散(同一个服务的多个 VM 在同一个宿主),某一个宿主挂掉,影响也不是很大。但是随着业务的变化发展,再做服务化拆分之后,线上的服务基本上没有几百台做成一个大集群的情况,都是十几台,或者几十台这种小集群。 如果我们有一个 10 台 VM 的服务,其中 5 台在一个宿主上,那么这个宿主一旦挂掉,服务整体的承载能力就砍掉了一半,风险很高,高峰期如果掉一半,这个业务就瘫痪不可用了。针对这个问题,SRE 团队跟云计算的同学做了一个持续了半年多的优化,将 VM 打散率控制到了 90% 以上,最终在同一个宿主上,同一个服务,不会多于两台 VM。 第三个问题,完善调度成功率。经过 SRE 和云计算同学的合作努力,现在的成功率已经达到了 3 个 9 左右。 上图是我们云计算基础设施网络相关的架构图,可以看到上面是公网的入口,流量接入大部分都是走的 BGP 链路。往下是多机房间的高速专线,专线的稳定性经历了线上大规模业务的校验,像外卖、团购、酒旅等,都是做多机房部署的。 另外就是高冗余的网络架构,基本上每个节点都有一个冗余设备,能保证在其中一台设备出现问题的时候,整个流量不受影响。入口和出口接入了一些自研的组件,像 MGW、NAT 等,使我们对流量的管控变的更灵活。 美团点评应该是美团云最大的用户,美团云能给美团点评带来的收益有完善的 API 支持、高度定制化资源的隔离、调度机制,还有多机房光纤直连以及较高的资源利用率。 运维自动化 随着订单量和机器数的高速增长,为了更高效的运维,我们不得不往自动化的方向发展。 在自动化演进的过程中,我们总结出了自己的一套方法论。 复杂的事情简单化。比如引入云平台,基础设备管理都通过云平台的系统来做,把底层相关的东西全部封装,最终 给我们的就是接口或 Web 界面。 简单的事情标准化。如果你想做流程或者自动化,没有一个统一标准的话,你要考虑的点就会很多。所以我们在主机、域名等资源的命名、系统基础环境、上下线操作等方面,出了很多的标准,这些标准经历线上的实践打磨最终形成统一的规范。等标准都成型之后,我们再引入流程,比如创建一些机器,我会列出需要的操作,然后根据标准来做 SOP,先流程化再自动化。我们通过代码把手工的工作释放掉,最终达到了一个自动化的水准。
这是服务树,它包括线上的云主机、服务及服务负责人的映射关系,根据不同的层级做一个树形的展示。它将多个周边系统进行打通,因为上面有标签,通过这个标签能识别唯一的服务。目前我们打通的系统有配制管理系统、容量系统、监控平台等,还包括线上主机的登录权限。 另外最新的一个成本核算,服务树也已经打通,通过服务树的节点,只需要进行简单的操作,就能看到每个事业群的成本情况。 上图是我们创建机器的一个简单流程,首先由技术人员发起流程,然后到流程中心,流程中心从服务树获取服务的基础信息,然后将信息发送到运维平台,运维平台根据这些信息去云平台创建机器。之后云平台会返回到运维平台,运维平台将创建好的机器加到流程中心提供的服务节点下,同时调用配置管理系统对机器进行环境初始化,初始化完成后会自动添加基础监控信息。之后调用部署系统,对服务进行部署。部署之后,服务根据它的服务的标签,最终注册到服务治理平台,然后就能提供线上服务了。相当于只要技术人员发起,整个流程都是能自动完成的。 自动化这块就简单介绍这些,下面介绍一下目前的现状。 如上图所示,现如今公司规模变得很大,我们对此做了一些相应的拆分,图中红色的部分全部由云平台来负责,从最初的接入层到底层的一些基础设施,比如机房、网络、主机,全部由云平台来封装。中间又拆封了一层,这一层是由 SRE 来负责。 现在流程系统已经做得比较完善了,接下来我们新的探索目标就是数据运营这块。首先是故障管理,针对线上故障做一个统一管理,包括故障发生的时间、起因、负责人,根据它的严重程度,分为不同的故障等级。我们也会针对故障的后续改进持续跟进优化,保证每一个 TODO 都能落实。 另外一点,通过故障平台我们对所有的故障进行汇总,系统能根据汇总的信息对不同的故障进行分类,也能总结出我们线上不同故障类型的占比,进而做一些定点的突破。 在故障管理之后,我们又做了一些数据挖掘相关的工作,在初期,我们运维的数据主要来自于监控平台或者是业务主动上报,而在现在这个阶段,我们会主动挖掘一些信息,比如线上服务的请求量、响应时间等来做一些定向的分析。 如上图所示,我们的使命从最开始的变更与救火,到现在已经逐渐转变为防火与驱动变革。通过数据运营,我们能反向的驱动业务。工作核心是稳定性,这一点一直没变。 我们可以把运维理解为运营维护,运营是指通过经验积累、数据分析,推动整体服务质量的改进;维护是针对线上的服务,还有业务的需求,我们能够用专业的技术来满足他们。 下面讲一下在稳定性保障方面的实践。 业务稳定性保障实践 首先,我们来总结下故障的起因,同时举一些例子来说明具体的情况。 1、变更。美团点评线上服务的日常发版超过 300 次,另外还有一些运维的基础变更,包括网络、服务组件等。举个例子,线下做变更的时候,我们写一个简单的 Nginx 配置,如下图所示。 它和线上写的配置,在红色部分的顺序发生了变化,如果 rewrite 的指令在 set 指令之后,可以生效,结果符合预期。当我们把 rewrite 指令前置后,break 指令会被先执行,会结束整个重写过程,rewrite 之后的 set 就不执行了,导致配置上线之后,Nginx 找不到后端的服务,整个线上的服务就崩溃了。如果做好充分的灰度,我们就能及时发现问题并解决,但是我们在上线的过程中缺少了灰度过程。事实上,标准的 SOP(标准操作程序)应该是上图中的五步,但是负责变更的同学想当然也好,或者是粗心大意也好,在线下测试以后没有发现异常,就直接全量上线了,最终酿成大祸。 2、容量。一些大的节假日或者秒杀抢购都会带来大流量,异常流量攻击或者爬虫抓取也会带来流量突增。如下图所示,这是猫眼发生的一次较大的事故,这个故障主要的原因是最底层的、最后端的服务容量不到位,在流量发生大的变化的时候它没撑住,关键的服务峰值上涨 5 倍,DAU 相交元旦(前一个历史峰值)涨了一倍。 主要是两个问题导致的,一个是我们对于大的活动评估不准确,还有一个是它的容量不对等。相当于前端的应用评估是可以撑住的,但是后面的底层没有撑住,前端的流量都打到后端,后端撑不住,整个服务就挂了。由此,我们至少要做到两点,第一要知己,了解自身能承载的容量情况,这点我们可以通过压测或者一些历史数据的参考获取到这个容量。第二要知彼,准确知道前端过来的流量究竟有多大,可以通过运营和技术的联动,在出现一些大的活动或者大的节假日的时候,通过他们的容量评估和历史数据做出相应的判断,进而做一些容量的准备;另外,要了解下游系统的容量水位,一旦低于本服务的容量,我们就要做好限流,并且提醒下游服务做相应的容量匹配。 3、隐患。隐患主要针对系统设计存在的一些缺陷,还有一些组件的交叉调用、关键报警的缺失、链路容量不对称等。这类问题是比较难发现的,需要我们深入进行研究。这方面的实例我们可以看下下面这个图,没有操作之前,它的数据包是沿着绿色的线走的,做了操作之后,部分数据包就沿着红色走了。变更前后的主要影响是,红色链路的数据包 session 发生了变化,因为最初的时候 session 在 IMGW1 上,在链路发生变化后,对于 TCP 有状态的连接,再往后就找不到它后端了,数据包没办法发送过去,这时候数据就丢失掉了,无法连接数据库,这个业务就挂掉了。 不过业务层在设计架构之初,应该考虑到网络不稳定的情况。针对上面的隐患,大概有三个方法。 第一个就是做全链路的演习,模拟一个真实的场景,经过模拟演习,还是多多少少能 出来一些问题。我们可以针对这些问题,去完善我们的故障预案、修复线上漏洞,做演习的时候也能验证我们的报警系统是否正常运转。 第二个是 SLA,对于服务定一个比较严格的稳定性指标,并针对这个指标持续不断的优化。比如我们线上 HTTP 接入的服务,针对 accesslog 中的状态码和响应时间提炼出一个稳定性指标,这对于服务本身的稳定性情况,就多了一个可参考数值了。稳定性指标波动服务必然有问题,这时候我们就要针对它波动的点进行相应的分析,根据分析,最终能找到一些隐患。指标这块,要做到用真正的数据来反馈出线上的稳定性。 第三个就是做故障的管理,每个故障都能找到问题,TODO 能落实,各个故障的经验总结,也能共享到多个业务线。 经验总结 事故之前(比如标准 SOP、容量评估、流量压测)的核心就是要防范于未然。 事故之中的核心是快速止损,查找问题是一个相对来说难度比较大,也比较漫长的过程,因为这个时间是不可控的。但是如果我们提前有好的应急预案,就能达到快速的止损。此外,还要有服务的自我保护,还有一点,沟通也是很重要的。最开始出现问题的时候,其实是比较乱的,因为大家发现问题都很急,很多人都在问原因,这时候你问原因是没有用的,因为大家大部分是不知道,知道的话就能给出解决方案了。所以这时候需要一个完善的沟通机制,正确的时间反馈正确的消息,反馈的原则是少说表面现象,尽量说一些对于问题定位或者是对于止损方面能够有帮助的信息。 事故之后,像 TODO 落实、完善预案之类的,核心点就是吃一堑长一智,相同的问题不能发生第二次。
用户体验优化 首先从用户端开始,用户在访问我们线上业务的时候,流量是从公网到私有云,再到 Server。公网问题主要有网络劫持、多运营商环境、不可控的公网链路等。对于 Server 的话,主要就是一些传输层的协议,或者应用层的协议的问题,目前大部分业务交互还是用的 HTTP 1.0/1.1,其实 HTTP 这个协议也是需要改进的,它不太适合做频繁的业务交互。 针对这些问题,我们都做了一些尝试: 首先在公网接入这块启用 BGP,我们现在已经做了自建的 BGP 网络,不用再关心多运营商接入的问题。只需要采用 BGP 网络,数据包在公网传输寻址的时候,就可以进行最优的选路了。 面对劫持问题,我们尝试了 HTTP DNS 的方案,同时也在尝试 Shark,就是类似于公网链路加速,相当于我在用户的近端部署一个 Server,在 App 上嵌入 SDK,用户通过 App 发起的请求不用做 DNS 解析,而是先发到 Shark(参考之前的博客“美团点评移动网络优化实践”)上,再由 Shark 与后端服务交互。目前通过多种手段的持续优化,劫持问题已经少了很多。 针对业务交互的协议,上线了 SPDY 协议,对于频繁交互的业务提升还是很明显的。目前正在测试 HTTP 2.0,Server 端对于 HTTP 2.0 的支持还存在少量 bug,努力修复中,希望能早日用上。
未来展望 首先技术上,目前我们自动化这块做得比较好,还会持续做,下一步就是智能化。为什么要智能化呢?其实主要面临到一个瓶颈点,有些问题是不能通过自动化解决的,比如说前面提到自动故障定位,它的决策性很强,需要很多步的决策,并不是通过程序就能直接搞定的。我们现在正在尝试一些 AI 的算法,引入人工智能来做突破。 产品方面,我们现在做的所有工具,经过线上业务大规模的校验,正在往产品化的方向发展,希望能把它做成成型的产品,放在美团云上,能给美团云的用户提供服务。不只服务于我们自己,也服务于他人。 最后是技术架构,美团点评发展过程中一些疑难问题的解决方案,或者针对挑战的经验积累,经过线上大规模业务的校验,最终能形成一些成熟的方案,它能为美团云上的用户提供最前沿的技术参考。 云是大势所趋,它能把很多底层的问题封装起来,让我们有更多精力去做更重要的事情 原创:普存
|