http://www.ox-holdings.com

使用云计算工具的思想和实践方法也是独立于工具存在的新匍京a奥门:,我们的实时通信服务发生了故障

摘要即时通讯云 LeanCloud 3月29日因少量大用户量应用的高在线量而发生了连锁服务故障,这个问题相信不是第1次发生,也不会是最后一次。对于即时通讯云服务商来说,要想在成本和服务质量上达成平衡,暂期内只能是个梦。2016 年 3 月 29 日晚间,LeanCloud 平台上的多个应用进行了推广活动,激增的访问量给我们的数据存储和实时通信服务带来了较大压力。从 20:50 至 22:15 有多次流量高峰出现,我们多台 Web 服务器的网络吞吐包超过虚拟机的能力极限,内外网通信中断,从而导致 HTTP 服务多次出现间歇性故障(数据存储 API 以及依赖于它的服务也都间歇性不可用)。具体情况汇报如下:故障时间20:53 - 21:03(持续约 10 分钟)数据存储 API 服务约 50% 的请求超时。21:17 - 21:40(持续约 23 分钟)数据存储 API 服务约 50% 的请求超时。22:00 - 22:15(持续约 15 分钟)数据存储 API 服务约 12.5% 的请求超时。故障总共持续约 48 分钟。影响范围本次故障只影响中国节点,美国节点的所有服务均工作正常。在故障期间凡是向 LeanCloud 平台发送过请求,并使用了数据存储服务的活跃应用都受到了影响;我们的统计服务也在短时间内无法正常接收来自应用的事件上报。事故过程20:52:内部监控系统报警,显示多个 Web 服务器节点出现故障。我们立刻上线进行紧急处理,在排除后端服务问题之后,开始追查前端资源和带宽配额。21:03:由于部分应用流量回落,同时也由于我们临时大幅增加了出口带宽,服务暂时恢复正常。21:05:我们开始扩容前端机集群,以应对接下来可能再次出现的流量高峰。21:17:前端机扩容时碰到了虚拟机 OS 故障以及网络环境问题,未能及时完成。此时恰好部分应用又迎来一次流量高峰,前端机再次吃紧。21:30:修复过程将近半小时,于是我们启动了公告和通知流程,在微博和用户群里发出通告。21:40:流量自然回落,前端机再次恢复正常,我们的平台开始正常处理 API 请求。22:00:线上部分前端机出现物理故障,我们又开始对它们进行紧急处理,期间有大约 1/8 的 API 请求丢失。22:15:新的前端机节点经过手动处理后终于达到可用状态,并加入集群,完成了扩容,至此全部服务彻底被恢复。后续改进措施增加新的监控措施,对前端机网络入包量进行监控,防止网络转发量超过 VM 能力限制。调整前端机 VM 配置,使用高包量机型,增大前端机的处理能力。改进前端机扩容方式,使用 docker 镜像来加快新节点部署上线的进度。公告流程中增加短信通知渠道,确保信息及时通知到开发者。

故障说明

摘要即时通讯云服务商LeanCloud 2016年6月30日因一组负责实时通信服务数据统计的缓存机器发生故障,而导致雪崩致使即时通讯服务瘫痪43分钟之久!以下消息来自LeanCloud官方:6 月 30 日晚上 8 点左右,我们的实时通信服务发生了故障,导致大量应用的终端用户无法登录和发送消息,时间持续约 40 分钟,详细情况汇总如下。故障时间2016-06-30日 19:58 - 20:41(共计 43 分钟)影响范围LeanCloud 国内节点的实时通信服务受到影响(无法登录和发送消息),其它服务正常;美国节点一切服务正常。事故经过19:58 一组负责实时通信服务数据统计的缓存机器发生故障,导致用户登录或发送消息出现阻塞,类似操作开始消耗内部线程池资源;20:05 线程池资源耗尽,所有用户登录过程都会失败;20:22 确定了故障原因,开始重启缓存服务程序,但是服务程序所在机器因为压力过大失去响应,转而重启物理机器;20:33 缓存服务恢复正常,登录和发消息等请求开始恢复正常(为了加速我们新增了部分实时通信服务程序,以增加响应能力);20:41 实时通信服务恢复正常。下图中的黄线是故障时段前后的登录请求数量变化趋势曲线,与上述故障时间线吻合:后续改进措施聊天服务监控程序改由 Marathon 来自动部署并执行。该监控程序因前期的一次操作而被暂停,结果未能捕捉到此次服务异常,所以我们加入程序化的手段来保证其始终运行。(已完成)增加对统计数据缓存服务的监控。(已完成)增加对于登录请求数异常变化的监控。(已完成)进一步优化实时通信服务的架构,针对所有环节做好容错,防止类似的阻塞操作再次出现。(一周内解决)即时通讯云 LeanCloud 官方网站:

Elasticsearch集群:ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。该架构中ES集群采用3个节点,这个3个节点都是候选主节点。这里我们主要用于轨迹查询,信息检索、日志系统等场景。

让资源分配随流量变化,流量变大时扩容,流量变小时缩容, 这就是伸缩。

在 LeanCloud 的最前端,除了负载均衡之外就是 API 服务集群,也就是实现 RESTful API 的部分。客户端应用通过 SDK 或直接调用 API 和它通讯。根据请求的类型,API 服务再调用后端的各个系统完成所需的功能。比如如果是统计服务的请求,事件信息会被发送到统计服务并最终被保存到 HBase 集群;如果是数据存储服务的请求,那么 API 服务就会调用 MySQL 和 MongoDB 集群完成数据访问。因为 MongoDB 存储了每个应用的大部分数据,所以不少服务都需要从这里获取一些信息,是整个系统中很重要的组件。

配置管理系统:提供应用的集中式配置管理,是基于java开发的配置管理。

为了实现无感知上线,我们先将旧节点的分发权重设置为0,负载均衡就会停止向旧节点导入流量,再等待1分钟让此前正在处理中的流量处理完毕,然后销毁旧节点,回收资源。每次上线变更,服务容器所在的ECS会发生变化,同时,线上流量在Mesos集群中漂移。

各位 LeanCloud 的用户,大家好。

首先大致梳理下车联网行业的特性有哪些:

实践

我们肩上承载着为数万开发者提供稳定服务的责任。周六傍晚事故持续的四个小时也是所有 LeanCloud 的同事最难熬的一段时间。我们了解到有的创业团队为了当天进行的一个活动,在过去的时间里非常辛苦地工作,而活动却受到了 LeanCloud 事故的影响。这样的事情让同为创业公司的我们非常地难受和惭愧。

虽然当前的运维体系还算比较规范,但是大多数运维工具都是开源的产品,只能满足部分功能需求。随着运维管控需求的增加,需要的熟悉的开源产品也越多。运维管理不够统一,运维人员通常需要熟悉和掌握很多运维系统,导致新手很难入手。

SLB API

我们希望通过这个详细的报告让用户全面地了解整个过程,并将尽一切努力降低未来发生类似事件的可能性。虽然任何人都没有办法完全保证服务中断不会发生,但我们会采取一系列措施避免可预见的问题,并确保在发生意外的时候能更快地恢复。为了保持改进过程的透明,我们开放了一个 追踪各项具体措施的 Trello board,用户可以通过它随时了解我们的执行过程。

1.1 数据流介绍

经典网络中的反例

LeanCloud 的多项服务在六月六日周六下午发生了大约四个小时的中断或不稳定。其中 16:10 到 19:09 为故障阶段;19:09 到 20:17 为限流恢复阶段。

痛点2:没有弹性扩容缩容能力,应对流量高峰代价高

工具

在故障阶段受到重大影响的服务包括:数据存储、网站及控制台、云代码、推送、工单系统、用户反馈、第三方登录、应用内社交;受到轻度影响的服务包括:短信、实时通信服务中获取聊天记录的 API;未受影响的服务包括:统计分析、离线数据分析、应用内搜索、文档。

数据库集群又包含多种数据库,例如MySQL数据库集群,MongoDB集群,Elasticsearch集群。

我们这三年来为了达成这两方面的探索和实践可以总结为下面这张图:

大约在 16:10 我们的运维工程师收到 MongoDB 集群内存不足的报警,在初步诊断后,确定原因为mesos-slave 启动的一个子进程占用内存太多,有可能是存在内存泄漏,所以我们开始终止各台服务器的 mesos-slave 进程。在这时我们发现 MongoDB 的其中一个 shard 中有三个节点因为可用内存不足进入异常状态,其中一个是 primary,所以我们开始重启其中两个节点。由于 MongoDB 2.6 在启动过程中需要校验数据并修复索引,所以这个过程很慢,而当时正是流量高峰期,这个 shard 剩下的节点不足以承担当时的负载,所以很快被压垮。由于 primary 的连接数被占满,这导致出问题的两个节点无法加入集群。在这种情况下,我们决定屏蔽所有 API 服务请求,并重启处于错误状态的三个节点。

PHP环境:采用Centos7 + PHP5.6.11

储存在云磁盘和对象存储(OSS)中的数据都是自动冗余的。

在这个过程中,除了事故本身,我们在沟通上也犯了一些错误。当用户询问服务恢复时间时,我们给出了过于乐观的估计,但因为以上所说的原因,多个 MongoDB 节点经过了多次重启,实际恢复服务的时间晚了很多,这给用户造成了进一步的困扰。

下图为公司业务架构图。分为三大业务平台,其中核心是车联网平台,其次是能力资源平台和第三方合作平台。

再举一例,当流量可以漂移后,ECS层面的稳定性也就不那么重要了,我们完全有能力在仅能稳定运行数小时的云主机上构建出能稳定运行数月的服务。当ECS死机时,运行在上面的业务节点都会由于健康检查失败而被标记为失效状态,此时容器调度器自动新建容器来让流量漂移过去,同时,运维机器人会自动重启死机的ECS,让它恢复活力。

我们把 MongoDB 从 2.4 升级到了 2.6。新版本对地理位置的查询,以及 count 查询的准确性有所改进,所以我们认为这次升级对用户来说是值得的。但新版本的一个负面影响是,因为每次启动时要检查索引,所以启动时间大大延长了。而如果 MongoDB 是在出错的情况下重新启动,会导致大量的索引被重新建立,进一步延长启动的时间。

数据存储集群包含数据库集群和分布式文件系统。

一种自动运维模式

我们知道这次服务中断给很多用户造成了实质性的影响。我写这封信的目的是为了向用户说明发生的事情,以及我们将如何改进产品和服务以降低类似事件发生的可能性。

MySQL集群:公司目前拥有几十套大大小小的数据库集群,有的采用一主2从的高可用架构,有的是双主架构,这些MySQL数据库主要用于业务数据库。随着公司业务快速发展以及用户规模的快速增长,对数据库的性能要求也越来越高,从原来的高配虚拟机到后来的高配物理机,后来物理机的本地磁盘IO也满足不了要求,接着就开始上给数据库服务上SSD硬盘。现在勉强能维持着,在不久的将来,即便是目前最高配置的单台数据库服务器性能也不能满足的时候,我们怎么办?数据库团队需要提前掌握和了解未来的解决方案是什么,比如说分布式关系型数据库?

使用漂移解决了保持设计容量的问题后,又遇到新问题: 到底为每个业务分配多少资源才合适?

为了更好地解释这次事故,我想先简单介绍一下 LeanCloud 的后端架构。以下是一个简化版的架构图。

用户通过下载并安装手机APP,注册登录App后用户可以在APP 上查看自己车辆的位置,轨迹查询,油耗,车辆故障以及交友,娱乐等功能。

从4层负载均衡迁移到7层

以下是LeanCloud Cofounder/CEO 江宏在LeanCloud博客对整个事件的说明:

摘要: 最近两年车联网发展受到政府部门、科研院以及各大互联网巨头的广泛关注和积极推动。从应用来看,主要包括两种模式:一是前装模式(即车辆出厂前安装),是乘用车厂主导或者与有相关能力的公司合作,例如上汽和阿里巴巴的合作。

云数据库

在此之后,这三个节点分别经历了多次重启,原因是出问题的 shard 大约有 10,000 个数据库,而新版 MongoDB 要验证每个数据库并修复索引。这不但使得重启很慢,而且因为数据库数量太多,这个过程会耗尽系统对子进程数的限制,所以在重启之后集群无法恢复正常可用状态。直到我们找到原因并调整了系统设置,各个节点才完成正常启动,集群恢复可用。

下图为应用架构,主要分为客户端接入层,负载均衡集群,应用服务器集群,缓存集群,消息队列集群,分布式服务集群,数据存储集群,运维管控集群等。

无感知上线

在这次事故中没有发生服务器端数据的丢失或损坏。

俗话说知己知彼百战不殆,我们要上云首先要充分了解自己业务和应用架构。然后在充分了解云上产品的特性,看看哪些产品可以直接被我们使用,哪些是需要我们的应用或架构做出调整的。下面我们来分析下智能车联网平台的相关架构。

举个例子,本来防止内存泄露一直是服务器程序设计的一大难题,现在流量可以无感知漂移后,我们可以通过监控容器的资源占用并利用运维机器人销毁使用内存过多的容器来释放被泄露的内存。当容器被销毁后,由于节点个数小于配置值,容器调度器会自动新建容器并让流量漂移过去。缓慢的内存泄露往往极难调查并且周期性影响服务质量,但现在已无大碍。

MongoDB 集群存储了所有应用除了统计和备份数据以外的其他数据。由于数据量巨大,所以我们对 MongoDB 进行了分片(sharding),让数据分布在不同 shard。每个 shard 又由 5 台服务器(节点)组成,其中每台都保存着这个 shard 的完整数据,这样不但可以承担更高的负载,也保证了即使其中一些服务器坏掉,数据也是安全的。每个 shard 有一台称为 primary 的服务器,所有对数据的修改都会首先在这台服务器进行,然后再复制到其他服务器,而读取可以从任何一台服务器进行。当 primary 出现问题时,会有一个自动选举过程从其他成员里选出新的 primary,让服务可以继续,这是实现容错的方式。

1.3 传统IDC架构痛点

综合上面介绍的工具和实践方法,可以推出一种比较通用的高可用建站模式。

为了更好地管理 LeanCloud 的大量服务器,我们在近期引入了 Apache Mesos,这是一个为服务器集群的资源管理提供高层抽象接口的系统。Mesos 会在每台受管理的服务器上运行一个 mesos-slave进程。

这个消息队列的痛点也是刻骨铭心,kafka是开源软件,曾经遇到几次故障都是跟kafka有关系,在0.8.1,遇到kafka删除topic的功能存在bug,随后升级到09版本,不巧又遇到09版本kafka client的BUG,这个bug导致多分区多consumer时rebalancing可能会导致某个分区阻塞。后来升级kafka10版本,但是10版本的消费方式和08版本有差别,没办法又对消费程序进行改造。总之在我们使用kafka过程中遇到太多kafka的bug而导致的故障了。而我们中小企业技术能力有限没有能力第一时间修复这种开源软件的bug,处于非常被动和无奈的局面。

高可用: 保证公司的业务流和现金流持续正常流动,不受服务不可用或服务质量下降的影响。高利用: 在保证效果的前提下,尽可能少的购买资源并把购买的计算资源充分利用起来,不闲置,不浪费,将成本降至最低。

在限流恢复阶段受到重大影响的服务包括数据存储、网站及控制台、云代码、推送、短信、工单系统、用户反馈、第三方登录、应用内社交、统计分析、离线数据分析、应用内搜索、文档、实时通信中获取聊天记录的 API。实时通信在这个阶段未受影响。

对于缓存最大痛点在于运维,经常出现因磁盘IO瓶颈导致的redis集群故障,以及因用户快速增长需要经常对Redis集群进行在线扩容等。而且Redis运维都是只能是手动运维,工作量大,且容易误操作。因Redis集群而导致的故障不计其数。当然也跟当时的应用强依赖相关,Redis集群故障就导致整个应用也挂了,这是应用系统设计的缺陷。

具体到伸缩的实现,我们使用Zabbix监控各容器的资源占用,资源占用过高或过低的状况都会触发Zabbix调用TidyMaid对应的Web API请求伸或缩,TidyMaid再调用Marathon和阿里云对应的Web API完成伸缩操作。

虽然实际上系统间的关联比这个图要复杂,并且有一些做异步处理的系统没有画出来,但用以说明问题是足够的。

车联网行业用户的月活是非常高的,这个很好理解,因为汽车现在人们出行的必备交通工具,基本上只要一出门就会用车,一用车设备就上线并采集数据上报到平台;每天3小时的平均在线时长,因城市拥堵程度不同而不同。

冗余

架构总览

2、 早晚出行高峰比较固定

我们选用的容器调度方案是Mesos + Marathon。Mesos将多台ECS的CPU和内存资源统一管理,无需关注容器具体部署到哪几台主机上。Marathon可以为每种服务配置多个服务节点并配合健康检查来实现高可用。如果健康检查发现一个服务节点无法正常提供服务,Marathon就自动新建一个服务节点来代替这个失效节点,令健康的节点个数始终等于配置值,让流量从失效节点漂移到新节点上。

郑重声明:本文版权归新匍京a奥门-最全网站手机版app官方下载所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。