谷歌、Facebook 大规模宕机!“裸奔时代”程序员该怎么办?
运行不稳定,宕机两行泪。
作者 | 阿木
责编 | 郭芮
3月13日,大量用户反馈Google云服务器出现异常,此次异常波及大量知名产品,如Gmail、YouTube、Google Drive等,普通用户更是数量众多。
无独有偶,Google爆出问题后不久,全球知名社交网站Facebook也被爆出瘫痪的情况。14日凌晨,多个国家的大量用户反馈在使用Facebook时出现无法登入、无法发帖等问题,另外Fackbook旗下的Instagram以及WhatsApp也出现了同样的问题,让现代人暂时回到了原始的生活。
问题出现之后,14日Facebook在Twitter上公布了故障的消息,并表示公司已经组织人力在抢修问题。
虽然公告中并没有说明故障的具体原因,但Facebook指出此次事件并非受到DDoS(Facebook去年11月的一次故障,故障时间长达11小时,疑似遭遇DDoS攻击)导致。
就在大家都在猜测此次故障的原因时,今天Facebook发推文正式回应了此次故障的原因。推文中解释称此次故障是由于变更服务器配置导致,并表示当前宕机故障已经解决,服务在逐步恢复中。
至此,本次的Facebook宕机故障告一段落。
Google 云
3月13日上午10:00左右,全球很多国家的Gamil用户反馈邮箱出现无法发送、无法下载附件等情况。截止下午14:00左右,根据平台统计已收到的Gmail异常报告超过4000次。受此次事件影响的国家主要为北美各国、南美、欧洲部分国家和东南亚的一些国家,如印度、马来西亚、新加坡等。
除了Gmail、Google Drive受影响外,还有用户反馈Google旗下的YouTube、Google Play、谷歌地图(部分用户反馈街景功能出现黑屏)等也受到不同程度的影响和异常。
3月13日上午11:00左右谷歌官方对服务器服务器异常的问题作出回应,证实问题确实是由服务器宕机引起,此次谷歌服务器故障影响到的国家和地区经超过70个。13日下午12:44左右,Gmail官方声明问题还在解决中,并说明最晚会在当天下午13:44公布最新的问题排查进展以及问题修复时间。
然后截止13日下午14:13,Google官方才宣布已经解决了Gmail 相关的问题,并向外界致歉。
14号上午11:09,Google官方正式公布了12日发生大面积宕机的事故分析报告:
报告中指出此次故障是由于SRE超载系统,导致Google云存储错误率大幅提高导致。问题具体过程为:
3月11日, Google SRE收到内部blob服务使用存储资源显著增加的告警;
3月12日,为应对blob 服务存储资源的增加,Google SRE进行了存储配置的更改,该更改导致系统的关键服务负载过高,导致引发一系列的级联故障。
以上为Google官方给出的云平台故障说明,另外官方也表示非Google云平台服务受到的影响后续会给出单独的故障报告。针对此次故障影响到的用户,Google表达了自己的歉意,并表示日后会积极采取措施提高系统的可用性,防止此类故障再次发生。
大规模故障事件盘点
而伴随着Google云和Facebook的宕机事件,一时间云计算是否稳定的话题又热了起来。联想前几天国内的阿里云大规模故障事件,本文就一起来盘点下这些年云计算大厂的宕机故障(排名不分先后)。
1、阿里云
2019 年3月2日23:55左右,阿里云华北地域部分服务器出现异常,此次故障波及大量阿里云用户,尤其是位于华北的互联网公司,大量公司收到服务器告警,一大波程序员、运维和运营人员不得不连夜起来处理问题。
此次故障最终在3月3日的03:10修复完成,阿里云官方给出的原因是部分后端服务异常导致。
国内公有云市场中,阿里云市场占有率最大,约为67%,此占比超过排名2-5的国内公有云厂商的市场占有率总和。从阿里云的官网文档看,国内约一半的网站都是部署在阿里云平台之上的——可以说,阿里云抖一抖基本可以影响中国的半个互联网江山。但是,作为国内云计算第一大厂,这已经不是阿里云第一次出现宕机故障了。
2018年6月,大量位于阿里云的网站出现大规模的访问异常,部分对象存储服务不能正常使用,导致很多用户图片服务出现问题,一些将网站验证码图片存放到此故障域的网站甚至出现网站不能登录的情况。事后阿里云官方宣称,此次故障是由于一次运维操作失误导致。
2016年10月,阿里云华东1地域部分服务器出现IO HANG,导致部分用户业务异常。
2015年9月,阿里云出现部分用户的正常文件被隔离的问题,事后查明此次故障原因是安全产品安骑士在进行版本升级时触发Bug导致。同一年阿里云启动”百倍时间赔偿计划”,承诺会给与用户相当于故障时间100倍的赔偿。
另外在2014、2013年等阿里云也曾出现不同程度的故障,由于当时上云的企业相对较少,因此影响的范围也相对较小。
2、谷歌云
除了前面我们已经介绍的谷歌云计算出现的故障,谷歌云计算在过去几年也出过几次较大规模的故障。
2018年2月15日,部分用户反馈谷歌应用开发平台出现数据库访问异常,使用此开发平台的用户基本都受到此次事故的影响,谷歌自身的PaaS服务Google App Engine 也是此次事故的受害者,被影响时间长达1小时。一些游戏玩家在此次事故中也被波及,因为很多的热门在线游戏使用了谷歌的服务。
2018年7月17日,谷歌云再次发生严重宕机故障,此次故障是由谷歌云中负责负载均衡的机器引起。故障波及到了谷歌旗下的应用开发平台App Engine、Cloud Networking和Stackdriver等。事件发生之后谷歌进行了一次更新,并于当天下午13:05分左右恢复服务。
3、AWS
2018 年3月2日,很多热门的在线服务不能正常使用,如Atlassian、Slack和Twilio等。最后查明此次事故是由AWS大规模的宕机引起,具体原因是AWS位于佛吉尼亚的数据中心遭遇强烈的东北风暴冲击,导致网络连接出现异常。
2018 年5月31日,AWS位于北佛吉尼亚的数据中心由于硬件故障,再次出现网络故障。此次故障持续时间约为30分钟,被波及的用户的数据最终不得不被全部转储。
2018年7月16日,AWS出现大规模故障,当天还是亚马逊的会员日(类似国内电商的双11)。此次故障在亚马逊的会员日开始几分钟后发生,导致当天的销售一度陷入瘫痪。另外AWS的核心EC2服务、WorkSpaces虚拟桌面服务和RedShift数据仓库服务都受到影响。
4、微软Azure
2018年4月6日,大量来自世界各国的用户反馈电子邮箱账户出现问题,许多企业用户无法发送邮件和Skype。微软最终确认故障是由于Office 365大规模宕机引起,此次故障波及范围极广,涵盖美国、亚太部分国家和欧洲大量的国家,其中英国在此次事件中受影响最为严重。
2018年6月17日,微软Azure因为数据中心制冷系统故障,导致存储和网络出现大规模异常。此次故障时间持续2天,导致用户不能操作服务器的时间长达5小时。
2018年9月4日,Azure位于圣安东尼奥的数据中心遭遇雷击,导致美国中南部地区的很多用户无法访问Azure。
2018年9月5日,来自多个国家的用户反馈无法访问Outlook或者Skype for Business,故障现象为当用户登录微软时会提示”受到限制”。最终查明原因为Azure后端身份验证系统在进行版本更新时引入了导致故障的Bug。
2018年11月18日,Azure部分机器发生宕机故障,导致很多用户反馈无法登陆Azure。此次故障从当地时间晚上11:39开始,影响范围包括美洲、亚太和整个欧洲。
过去的一年可谓是云计算的”中断之年”,几乎每个公有云巨头都没有幸免,其中一些故障更是耗时格外长,影响极其严重。
程序员该怎么办?
云厂商基本都会承诺99.99%的可靠性,从这些年云厂商的故障来看,谁都有可能会成为那0.01%。那么问题来了,我们改如何避免成为那0.01%?下面我们给出几条建议。
1、数据周期性备份
数据包括虚拟机镜像数据、容器镜像数据、数据库数据、对象存储数据、各种日志数据等。主流的云厂商一般都会提供完备的数据备份策略,可以根据数据重要程度选择备份频率,进行周期性的备份。
在出现故障时可以利用已备份的数据进行快速恢复,故障到恢复这段时间之内产生的数据可以利用各类数据的日志记录进行单独的恢复。
2、异地多活部署
异地多活,顾明思议关键点的点就是异地、多活。其中异地就是指地理位置上不用的地方,多活即不同地理位置上的系统都可以提供专业的服务。
判断一个系统是否是异地多活,一般需要满足如下两个标准:
用户无论访问哪一个地方的业务系统,都可获取到正确的业务服务;
当某个地方的业务系统出现问题时,用户的请求调度到其他地方的业务系统也可获取到正确的业务服务。
多活部署一般指将相同的服务部署到多个中心,根据地理位置上的距离划分异地多活一般分为同城异区、跨城异地,避免将所有的鸡蛋放置到同一个篮子中。
同城异区
同城异区一般指的是业务部署在同一城市的不同区的数据中心中。例如在杭州部署两个机房,一个机房在滨江区,一个在建德区,然后将两个机房用专用的高速网络连接起来。
同城异区的两个机房,一般在地理距离上相距几十公里,通过高速的网络,同城异区的两个机房可以和同一个机房内几乎拥有同样的网络传输速度。
同城异区是应对机房级别故障的最优架构。
跨城异地
跨城异地指的是业务部署在不同城市的多个机房,而且一般要求两个城市的距离要远一些。比如将业务部署在距离较远的广州和北京,而不是部署在相距较近的天津和北京。
距离的增加可以解决一些不可抗拒的自然因素引起的故障,如水灾、地震、风暴等。但也会引入另外的问题,如传输距离远带来的网络时延问题,网络时延可能又会带来数据的不一致性问题。另外距离的增加也会增加一些其他的不可控因素,如骨干网络被挖断等,这些都会给多活的设计带来复杂性。
跨国异地
跨国异地一般只将业务部署到多个国家的不同机房中。
相比跨城异地,跨国异地的机房之间距离更远,因此数据传输的时延会更高,可能会达到几秒的时间。这种程度的时延已经基本满足不了业务的访问需求。
因此跨国异地在实施时一般是为不同的国家分别提供服务(如亚马逊中国的服务和美国亚马逊服务一般是分别部署、分别访问的,亚马逊中国中注册的用户不能登录美国亚马逊,反之亦然),或者用于只读类业务的多活(如谷歌搜索服务,大家只是搜索需要的信息,不涉及信息的修改,因此不会存在数据同步时延问题)。
相比单一数据中心部署,服务多活部署成本相对较高。所以大部分公司在进行多活方案的实施时,一般只对关键的核心业务进行多活部署,提高核心业务的安全性。
多活部署的方案有很多,典型的实现形式如混合云(用户本地私有云和公有云打通)、多Region部署(应用部署在同一云平台的多个Region之上)、多云部署(也称跨云,即将应用部署到多个云厂商的平台之上)。
(1)混合云
有自己机房的用户可以考虑使用混合云,将公司的业务一部分放到云厂商的平台,另一部分部署到自己的机房中,业务双活,自己机房和云平台上各有一份数据,且数据相互同步(可能有数据不一致的情况)。
正常情况下用户访问离自己最近的数据中心,当一个数据中心出现故障时,流量切到另一个数据中心。此种情况可能会出现两个数据中心数据不一致的情况,但起码可以保证绝大部分用户可以正常访问,后期可以根据数据库的日志修复不一致的数据。
此种方案的优点是可以将核心业务放到自己的机房,避免核心业务的上云迁移,同时也可保证数据的隐私性。
缺点是需要解决用户自己的私有数据中心和公有云平台的打通问题,联通双方的数据中心一般需要专线,因此成本上是比较高的。
(2)跨region部署
业务部署到同一个云厂商的不同region中,如一部分部署在华北,主要处理靠近华北用户的请求;另一部分部署在华东,主要处理来自靠近华东用户的请求。
当其中一个region出现大规模故障,影响到用户的访问时,及时将该部分的请求切往另一个region。这样虽然新接过来的请求处理相对较慢,但保证了绝大部分用户可访问我们的服务。流量切过来之后还要根据情况评估当前的region资源是否可以支撑这些新增的流量,不够的话就需要及时扩容了。
跨region 部署建议使用专业的云厂商平台,防止引入跨region引入更多的故障(公司内某跨region服务曾出现一个region的服务挂导致全部region服务挂的问题)。
此方案的优点是多套业务部署在同一套云平台,稳定性方面相对较好、成本相对低一些。多个region中数据备份、告警配置、扩容等方式一般是一样的,因此学习成本也会节省很多。缺点是多个region使用的是同一家云厂商可能存在关键节点故障,导致多个region不可用的情况。
(3)跨云部署
跨region部署可以很大程度上帮助我们避免因为云厂商某个区域出现大规模故障导致服务不可用的问题。但也还是存在一些问题的,如云厂商对多个region同时进行升级,触发Bug,虽然这种情况很少。
跨云部署也称多云部署,即将业务部署到多家不同的云厂商平台之上,这样即使一个云平台出现大规模故障也不会影响到另一家云厂商,从而进一步提高我们的服务安全性,当然此种部署方式也会引入更多的技术复杂性。
跨云部署这种方案成本相对较高,但是稳定性上也是比较好的。此种方案的优点是业务部署在不同云平台之上,一家云平台大规模故障时一般不会影响到我们部署在另一家云平台之上的业务。缺点也是很明显的,因为是两套云平台所以两套业务的对接问题需要专门去解决,包括数据同步等。另外多套平台也会带来额外的学习成本。
总结
从以上异地多活的描述看异地多活似乎很强大,但实现异地多活并不是没有代价的。一般会有很高的代价,具体表现为:
相比单活系统的复杂度会发生本质的变化,需要专门设计复杂的异地多活架构,且需要专门设计平滑的迁移方案,另外整个方案的实施周期也相对较长;
总的成本会上升,毕竟需要多部署一套或者多套系统。
以上多个方案没有绝对的好坏之分,不同部署方式各有利弊,实现成本、技术复杂度也是各不相同,需要本着合适的原则根据实际情况进行选择。
作者:王洪鹏,运营有个人公众号新新生活志。目前任职网易云计算技术部高级工程师,近3年云计算从业经验,爱读书、爱写作、爱技术。
声明:本文为CSDN原创投稿,未经允许请勿转载。
【End】
热 文 推 荐
☞虎口夺食! 打破Facebook谷歌垄断, MIT大神和他的区块链数据库传奇! |人物志
☞以安全之名:2019年DevSecOps社区调研白皮书解读
☞身为程序员的父母,你年薪多少才能让“码二代” 不输起跑线上?
System.out.println("点个在看吧!");
console.log("点个在看吧!");
print("点个在看吧!");
printf("点个在看吧!\n");
cout << "点个在看吧!" << endl;
Console.WriteLine("点个在看吧!");
Response.Write("点个在看吧!");
alert("点个在看吧!")
echo "点个在看吧!"