万台服务器一人挑的奥秘

本文根据 2018 GOPS·深圳站演讲整理发布

作者: 张黎明

作者介绍:张黎明,SNG组件运维团队负责人,有八年的运维经验。参与了国内社交平台、Qzone发展壮大到成熟的过程,也参与了SNG系统标准化、大规模组件运营推广,自动化运维等项目,在海量服务运维方面有一定的心得,所以今天给大家分享一下具体实战。

首先,来说一下我们的组件运维团队的职责范畴:负责整个SNG接入和逻辑层业务的运营维护,有1.8万的域名,3000个业务模块,4万台设备,单人运维设备超过2万台,这么大的规模,我们面临五大挑战。

第一个挑战,大家都知道,中国幅员辽阔,横跨八个时区,有30多个省级单位,上万个域名如何保证就近接入?我们机房是上海、天津、深圳三地分布。考大家一个题,江西离上海近还是离深圳近?(现场问答互动)回答上海和深圳都是不完全正确:) 其实是江西北面离上海近,江西南面离深圳近。

我们在招运维的时候,还要求运维上通天文、下通地理才能干好,这显然不靠谱。中国有三大运营商,电信、联通、移动,还有很多小的运营商。中国有一个段子,世界上最远的距离不是天涯海角,而是你在电信、我在联通,相信大家做运维这个体验特别深刻,所以我们要尽量避免跨运营商。

第二个挑战,自从苹果启用ATS安全规范之后,域名支持https接入就成为标准了,https证书是有有效期的,需要不断的扫描、续期、更新。上万个域名的https接入如何高效统一维护,由运维完全搞定这个问题,这是面临的第二个挑战。

第三个挑战,一个人运维服务器超过万台的时候,你会发现每天名下有几台设备宕机是一个常态。像前面讲的,你不能在床上躺下了马上就起来,运维也是人干的活,我们如何保证宕机无需运维干预自动处理,而且还对业务无损。

第四个挑战,互联网中有一句话上线容易、维护难,互联网服务的运营维护周期比研发周期长,一个产品的研发周期,开发出来就几个月,但是运营维护的时间往往是几年甚至超过十年,很容易进入长尾死而不僵的状态,所以对运维也有挑战。

第五个挑战,大规模的缩扩容。比如说在春节、元旦这些节假日用户都喜欢在空间发感想、在群里发祝福,社交网络还会借势推波助澜一把,在节假日的时候搞一些活动,红包每年都搞,大家happy的节假日就变成我们运维的苦难日,因为涉及到大量设备上线、模块扩容,这是我们面对的第五个挑战,如何应对大规模的缩扩容。

本文从3方面进行阐述如何应对挑战

1. 海量服务的基础架构

我将从海量服务的基础架构、在运维过程中坚持的一些原则和支撑大型活动事件的技巧三个方面来分别阐述我们如何应对上述的挑战。

首先看一下腾讯SNG的基础架构。用户一个请求过来之后,任何一个访问首先是DNS查询,查询得到TGW和STGW的网关IP。这个TGW与业界开源的LVS和商用的F5是类似的东西。请求经过网关的负载均衡,到web层服务器,然后到逻辑层、存储层,图中间的织云路由是内网的负载均衡系统。我们的整个访问链路做到了三个基本点:第一,做到名字服务实现没有调不走的流量,这对运维是非常重要的。第二,容错做到没有不能宕机的设备,也就是没有不能死掉的设备。我们在网上看到一些段子,运维请法师来机房开光保佑不要宕机,其实求佛不如求己。第三,统一框架提升研发运维效率,保证服务的基本质量,对于运维这有很大的意义,后续我会重点阐述。

牛顿说,如果我看得比别人更远,是因为站在巨人的肩膀上。如果我们能够运维万台服务器,是因为我们站在巨人的肩膀上,踮起脚尖,做了一次一米八的眺望。

巨人的肩膀,一个是GSLB,是腾讯自研的DNS服务,通过识别LocalDNS出口IP国家+省份+ISP属性,然后给对应请求返回相应的IP,实现就近接入。北京、上海、天津每个地域有三大运营商+中小运营商出口CAP,然后再加上香港,所有海外的通过香港接入的方式,根据运营商来进行调度,这样一个是避免了跨运营商,二是做到运营商网络出口故障快速切换,依赖的就是GSLB的两点:第一,GSLB有一个强大的基础数据库,它有全面而精准的IP地址库,国家和运营商的信息准确率做到100%,省份的信息准确率做到98%,我们通过亚洲网络中心和中国网络中心的数据、运营商路由数据等通过一些算法校验得到ip地址库的数据。第二,我们拥有各IDC机房对各地用户覆盖质量的实时数据,通过机房拨测和前端页面的一些js抽样上报得到这个数据。

第二个巨人的肩膀是TGW,也就是腾讯的网关系统。2012年之前腾讯也使用了LVS tunnel模式,但是腾讯的业务发展太迅猛了,特别是游戏很快面临一个问题,外网资源耗尽。这种背景下,TEG的基础架构部推出了TGW这个系统。它的最大特点是能够收敛外网IP,只需要一个外网IP,所有数据包的进出都是通过TGW,对后端真实的服务器是没有外网需求的。LD本身的VIP怎么做到高可用的呢?通过OSPF路由一致性协议,一般是4台为一个集群,共享这个VIP,任何一个LD挂掉之后都不会对这个VIP产生影响。

另外,TGW还做了多通接入,每个机房有三大运营商的出口和CAP的出口,我们部署的服务器对运营商机房没有要求,电信的机房一样有三网+CAP的出口。以前用LVS tunnel模式的时候,电信的容量必须靠电信机房的服务器,所以对服务器机房的限制就非常多。

除了外网IP收敛之外,TGW也支持4/7层,特别是在7层,可以做到几百域名共享一个外网的VIP,当然TGW LD 集群所在的机房都是万兆,承载能力非常强。

第三个巨人的肩膀是STGW。你可以认为跟TGW是差不多的,它只是在TGW基础上支持了https,自从苹果启用ATS安全规范之后,新上线域名默认就会支持https接入,因为你说你的网站不支持https就不好跟人家打招呼。我们面临的情况是域名特别多,在没有STGW之前,对于https的支持方式,开发或者运维都是自己上传证书到服务器,放在自己想放的路径下,每个人的style都不一样,证书没有统一管理,一旦人员流动,他做的这些事情就烂在生产环境了,所以出现很多证书没有及时续期和更新证书产生的故障。我们痛定思痛之后,对全网的域名推动上STGW,所有证书统一部署在STGW平台,申请、续期、更新等操作全部由组件运维团队来做。证书通过域名一个一个的去扫描是否过期的可靠性就比较低,如果是STGW托管,我们直接从服务器上读取证书的过期时间,这是不可能失误的,而且证书安装更新的环境更加纯净,变更风险小了很多。

第四个巨人的肩膀是织云路由。刚才sam也做了详细分享,它的定位是内网的名字服务系统。它是我们的用户请求经过TGW到内网之后,是接入层到逻辑层,逻辑层到存储层的寻址系统。有一些企业在内网负载均衡也会用F5,我们为什么不用呢?是差钱吗?我们根本不差钱。讲一下我们为什么不用,我们的路由是强嵌入式的,对用户主调是有要求的,这里有两个函数,接口非常简单,首先通过GetRoute获取ip端口,之后去访问,然后你访问我是成功还是失败,通过对API RouteResultUpdate上报,对上报数据进行统计之后,做一个负载均衡的决策。

我们的织云路由跟业界大家熟知的东西到底有什么区别?我来详细介绍一下。刚才说了,我们不差钱,为什么要用织云路由呢?因为我们对服务的精细化治理有要求,所以它本身是一套服务精细化治理的解决方案。

它唯一的劣势是在使用门槛方面需要业务调用API代码,但是这也带来了好处,相对F5和LVS这种无侵入的方式,基于调用方上报织云路由实现了后台服务质量的精细化管理,织云路由的成功率是SNG后台服务质量的考核标准,通过这个推动后台服务的质量。

二是负载均衡根据业务上报的成功率设置了过载保护的能力,后台能力不行的时候会把多余的请求拒绝掉,只给能够成功的请求。与其把请求全部发送给后端,把后端压死,不如在前端获取IP+端口的时候就告诉你过载了、不要请求了,把请求控制在后端能够承受的极限来发。

三是容错能力,F5和LVS的容错只能探测到端口的连通性,而织云路由可以自定义容错场景。四是相比F5和LVS的四层代理,对于被调服务获取主调IP会有很大的困难,对服务问题追踪是一个很大的门槛,而织云路由不会造成这种困扰。

第五个巨人的肩膀,逻辑层统一框架SPP。后台框架对运维的意义重大,SPP由Proxy、Worker和Controller三部分组成。开发可以很简单就写一个鲁棒性强的高大上后台server,Controller对Worker和Proxy有监控能力,如果发现Worker和Proxy有问题会重新拉起,还可以通过配置Worker的进程数来控制程序的并发能力。

统一框架对运维的意义:

一是我们可以跨业务实现维护策略的统一。

二是网络框架和业务逻辑SO分离管理,运维具备快速升级框架的能力。有很多统一框架是集成的,和业务程序包打在一起、编译进去的,当框架推出一个新的优化,想全网快速普及的时候,要让所有业务系统重新编译发布。而我们的框架和SO分离的管理方式,框架是由运维统一部署的,SO是由业务部署的。框架有一个好的特性或者紧急的BUG要升级的时候,运维可以快速升级框架,不需要重新编译就可以做到这一点。

三是运维专业度提升。大家知道,铁打的业务,流水的兵,人员流动是非常快的,我们统一框架之后可以做到运维在问题定位方面具备更强的能力,专业度的提升非常大,框架数据包的流转流程非常清楚,运维就比开发更懂他写的这个程序,当然除了业务逻辑除外,大部分方面运维比开发更专业。

四是Controller对proxy和worker具备监控和起停的能力。C语言后台程序经常出现coredump,指针使用不善就会core掉,Controller使worker进程即使挂调也能够快速恢复。

2. 运维实践中总结的几个原则

说完了巨人的肩膀,接下来说一下踮起脚尖一米八的眺望。如何让运维变得更加高效?

第一个原则是“名字服务原则”

前面说了,名字服务非常关键,我们要保证系统任何一个寻址都有名字服务。我们每年有上万台设备裁撤,没有IP是不能动的,所有IP都是可以变的。近10万台设备,每天几台设备宕机成为一个常态,名字服务和容错是自动化运维的基础之一,重要性我前面也讲了很多,那么这里我分享一下运维是如何去影响研发侧,把名字服务的原则落实的。

我们从三方面来做:

一是联合QA建立质量考核体系。我们把访问关系梳理好,和名字服务的访问关系来对比,发现哪些调用没有使用名字服务,从名字服务的覆盖率和QA推动所有研发必须用。这是中策,毕竟推动也不是那么容易。

二是后台框架支持RPC,封装路由寻址调用,让主调方在不知不觉中已经使用了名字服务,服务提供方就可以具备流量快速切换的能力。

三是拓展名字服务的场景,织云路由支持按照UIN的有状态寻址和一致性hash寻址,同时支持了DNS协议,降低接入门槛,这样来普及我们的名字服务。

第二个原则是“一致性原则”。

大家做过运维,我们SNG的服务是按照模块管理的。织云CMDB模块录入包、名字ID、配置文件、权限等资源。你要看录入的资源和现网使用的是不是一样的,所以我们运营的时候也遇到一致性的问题,我们对装包的权限进行了收拢,由组件运维这边统一控制,为了实现模块下所有设备包的一致性管理,不能有的机器装了、有的机器没有装,这会对现网带来运营风险。

配置文件方面,你通过配置系统发送到现网,有人篡改了,系统登记的和现网使用的配置不一致,只要你动这个配置就会出现问题,所以我们正在启动一个改造,开启强一致功能,把现网机器上的配置文件和配置中心的进行一致性对比,发现不一致就强制修改回来。同时,我们在想,配置管理为什要以文件的方式,而不能以Key-value这种内存键值对呢?使用Key-value,你不需要在本地文件进行读取,有一些是服务热重启的,有一些不支持,配置文件变更重启难免就会有影响,Key-value的模式天然的就是不需要重启的,这种方案也有很多实现。我们后续主推Key-value的方式,让生效时间和影响都变得最优。

权限方面,最开始我们按照IP去管理,后来发现IP模块归属变化之后带来冗余,而且每次扩容都需要对新IP单独申请权限,短板很大,所以我们就跟模块绑定,不是跟IP绑定,按照模块管理,只要在这个模块下就有这个权限,这个管理比IP管理要优一些的。

某种程度上,我们织云按照模块的管理维度,你这个模块绑定了哪些名字,这个模块的IP是不是接入这些服务,如果有的没有接、有的接了,对于你缩容的时候会产生风险,会有把某一个名字踢空的风险,所以我们定期进行比对,一旦发现有问题就派单去去处理,保持模块下IP和服务接入名字两者的一致性。

第三个原则是无数据原则。

这个原则是很重要的,对于我们接入和逻辑层,一个人维护2万台设备是非常关键的基础。我们要求所有的接入层和逻辑层设备无数据。首先对于上报超时这种假死状态的告警,因为它无数据,所以整个处理过程变得很简单,需要考虑的点比较少,有告警我们首先判断是不是接入层和逻辑层设备,如果是就可以直接重启。刚刚说了,我们的织云路由是具备流量自动恢复的,会在设备故障之后发现端口连通性恢复之后就把流量自动恢复过来,如果重启不能修复就看驻场能不能修复,如果驻场不能修复就退役了,如果驻场能够修复就可以继续服务,这种就是简单粗暴可靠的。第二个无数据还带来设备要求的简化,无raid,硬盘故障之后直接换盘重装。第三个无数据的要求,磁盘在保存尽可能多日志的前提下实现自动化清理。我们一步一步的缩短日志保存的时间,直到磁盘不告警为止,对我们来说骚扰就会变得非常少。

第四个原则是统一原则。

我们有统一后台框架、统一名字服务、统一配置中心、统一数据上报通道、统一包发布系统,这些是自动化平台的基础,因为统一带来维护对象的减少和对上层调用系统呈现出来的的简单,可以大大提升上层自动化系统的可靠性。我们有一句话,不要在沙盘上建高楼,底子没有打好,自动化程度很难提升上来。

3. 支撑大型活动事件的实践技巧

接下来说一下我们针对大型支撑活动事件的实战技巧。针对社交业务的活动、节假日做的事情,是比较个性化的,大家可以听一下,看看有没有什么启发。

我们大型活动的挑战:扩容设备量大、模块多、扩容状态跟进难,一个人要扩容一个模块还好,要扩容几十、上百个模块,你发现流程状态跟进很难。留给扩容部署的时间也紧,刚刚过去的2018年春节和红包活动,组件运维团队扩容641次,涉及535个模块,15701台设备,扩容操作要求在设备交付后一周内完成。

看一下春节扩容的大概流程。首先是资源申请,要进行资源合理性PK,然后要去采购,进行资源交付,之后要有虚拟化的过程,设备生产和扩容部署在织云,验证灰度和全量上线涉及到织云路由(通过织云路由调度流量)和监控系统(通过监控系统查看新扩容IP的服务质量)。活动搞完了,要下线,要进行设备隔离,整个资源的退还要在资源管理系统去做。我们面临和不同部门各个团队的沟通,各个系统单独操作的成本是很大的。打一个简单的比方,当你有15000台设备分配下来的时候,你要把它划到对应的模块,这个事情如果不用工具去做,人肉去操作都要搞两三天,而且还很容易出错。

织云对于单个服务的自动化部署流程:首先是部署准备,二是发布部署,三是发布自检,四是灰度上线。

首先是部署准备,检查一致性、检查设备连通性、获取资源、屏蔽警告。

二是发布部署申请权限、安装程序包、发配置、同步文件。

三是发布自检,启动软件包、进程端口扫描、治行测试工具。

四是灰度上线,一台灰度10%,调用变更体检,全量接入。

我们比较好的具备单个服务的自动化部署能力,但是对于我们应对几百个模块的同时扩容还不够。在这个基础上,我们做了批量部署的系统,各个系统对其功能对外都有接口化的能力,对外提供http接口,那么批量系统可以把各个系统的这些操作串联起来。

批量部署系统:一是集中展示和管理,各个步骤封装成原子接口,在统一界面操作。二是对接各个系统,比如说哪个模块扩容多少,在资源申请单的时候这是录入了的,批量系统根据资源申请单自动生产设备,把设备分配给相应的模块,批量在织云上发起扩容流程。三是规模效应,批量操作上百个业务模块。四是状态自动跟进,我们把关键节点的状态全部记录下来,在统一的页面上去展现,才知道这几百个模块扩容状态到底是什么样的,完成了多少,有哪些正在进行中、哪些失败了,便于聚焦扩容出现了问题的模块。

我们最终做到的效果就是能够在一周内把15701台设备600多次扩容全部搞定。春节期间的组件团队单人最多的时候运维超过2万台设备。

4. QA环节

提问:你们可以识别小运营商的多出口来调度到运营商吗?张黎明:我们中小运营商是调度到统一的CAP出口。

提问:小运营商走专门的出口?张黎明:对,电信、联通、移动不跨网,中小运营商我们有一个加速平台叫CAP,每个域名都会申请CAP的VIP。

提问:你们调度是根据机器密度还是根据业务?如果机器现在有问题了,你把机器的流量都切走,还是把理想的流量切到这里来?张黎明:比如说福建电信原来走深圳电信的服务,当我们一旦发现深圳电信故障的时候,它会调度到上海电信,因为我们三地分部,所以会有一个自动切换到上海电信的过程。

提问:根据业务来的吗?它只影响了一部分业务。张黎明:VIP故障一般都是运营商网络故障,挂在这个VIP下面的所有业务都会受影响,无一幸免的,这个VIP承载的运营服务都需要调度走

如何解锁更多自动化运维新技能?

来 DevOps 国际峰会·自动化运维专场

来自阿里,京东,华为,招行的四位专家手把手传授你经验

当然,这里还有更多高端,大气,上档次的精彩演讲

扫描二维码进入大会官网

点击阅读原文,更多惊喜⬇️