在 2018 年春节期间,组件运维团队运维设备超过 4 万,单人运维设备超 2 万。在海量服务运维过程中我们面临了哪些挑战?
我们的组件运维团队的职责范畴:负责整个 SNG 接入和逻辑层业务的运营维护,有 1.8 万的域名,3000 个业务模块,4 万台设备,单人运维设备超过 2 万台,这么大的规模,我们面临五大挑战。
第一个挑战,中国幅员辽阔,横跨 5 个时区,有 30 多个省级单位,我们的机房是在上海、天津、深圳三地分布,上万个域名如何保证就近接入?
考大家一个题,江西离上海近还是离深圳近? 答案是江西北面离上海近,南面离深圳近。
我们在招运维的时候,还要求运维上通天文、下通地理才能干好,这显然不靠谱。中国有三大运营商,电信、联通、移动,还有很多小的运营商。
中国有一个段子,世界上最远的距离不是天涯海角,而是你在电信、我在联通,相信大家做运维这个体验特别深刻,所以我们要尽量避免跨运营商。
第二个挑战,自从苹果启用 ATS 安全规范之后,域名支持 https 接入就成为标准了,https 证书是有有效期的,需要不断的扫描、续期、更新。
上万个域名的 https 接入如何高效统一维护,由运维完全搞定这个问题,是面临的第二个挑战。
第三个挑战,一个人运维服务器超过万台的时候,你会发现每天名下有几台设备宕机是一个常态。
像前面讲的,你不能在床上躺下了马上就起来,运维也是人干的活,我们如何保证宕机无需运维干预自动处理,而且还对业务无损。
第四个挑战,互联网中有一句话上线容易、维护难,互联网服务的运营维护周期比研发周期长,一个产品的研发周期,开发出来就几个月。
但是运营维护的时间往往是几年甚至超过十年,很容易进入长尾死而不僵的状态,所以对运维也有挑战。
第五个挑战,大规模的缩扩容。比如说在春节、元旦这些节假日用户都喜欢在 QQ 空间发感想、在 QQ 群里发祝福,社交网络还会借势推波助澜一把,在节假日的时候搞一些活动,QQ 红包更是每年都搞。
这样大家 happy 的节假日就变成我们运维的苦难日,因为涉及到大量设备上线、模块扩容,这是我们面对的第五个挑战,如何应对大规模的缩扩容。
本文从以下三个方面进行阐述如何应对挑战:
海量服务的基础架构
运维实践中总结的几个原则
支撑大型活动事件的实战技巧
海量服务的基础架构
我将从海量服务的基础架构、在运维过程中坚持的一些原则和支撑大型活动事件的技巧三个方面来分别阐述我们如何应对上述的挑战。
首先看一下腾讯 SNG 的基础架构。用户一个请求过来之后,任何一个访问首先是 DNS 查询,查询得到 TGW 和 STGW 的网关 IP。
这个 TGW 与业界开源的 LVS 和商用的 F5 是类似的东西。请求经过网关的负载均衡,到 Web 层服务器,然后到逻辑层、存储层,图中间的织云路由是内网的负载均衡系统。
我们的整个访问链路做到了三个基本点:
做到名字服务实现没有调不走的流量,这对运维是非常重要的。
容错做到没有不能宕机的设备,也就是没有不能死掉的设备。我们在网上看到一些段子,运维请法师来机房开光保佑不要宕机,其实求佛不如求己。
统一框架提升研发运维效率,保证服务的基本质量,对于运维有着很大的意义,后续我会重点阐述。
牛顿说,如果我看得比别人更远,是因为站在巨人的肩膀上。如果我们能够运维万台服务器,是因为我们站在巨人的肩膀上,踮起脚尖,做了一次一米八的眺望。
巨人的肩膀:GSLB
GSLB 是腾讯自研的 DNS 服务,通过识别 Local DNS 出口 IP 国家+省份+ISP 属性,然后给对应请求返回相应的 IP,实现就近接入。
北京、上海、天津每个地域有三大运营商+中小运营商出口 CAP,然后再加上香港,所有海外的通过香港接入的方式,根据运营商来进行调度。
这样一个是避免了跨运营商;二是做到运营商网络出口故障快速切换,依赖的就是 GSLB 的这两点:
GSLB 有一个强大的基础数据库,它有全面而精准的 IP 地址库,国家和运营商的信息准确率做到 100%,省份的信息准确率做到 98%。
我们通过亚洲网络中心和中国网络中心的数据、运营商路由数据等通过一些算法校验得到 IP 地址库的数据。
我们拥有各 IDC 机房对各地用户覆盖质量的实时数据,通过机房拨测和前端页面的一些 js 抽样上报得到这个数据。
巨人的肩膀:TGW
TGW 是腾讯的网关系统。2012 年之前腾讯也使用了 LVS tunnel 模式,但是腾讯的业务发展太迅猛了,特别是游戏很快面临一个问题,外网资源耗尽。
#p#分页标题#e#这种背景下,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
关于 STGW,你可以认为跟 TGW 是差不多的,它只是在 TGW 基础上支持了 https,自从苹果启用 ATS 安全规范之后,新上线域名默认就会支持 https 接入,因为你说你的网站不支持 https 就不好跟人家打招呼。
我们面临的情况是域名特别多,在没有 STGW 之前,对于 https 的支持方式,开发或者运维都是自己上传证书到服务器,放在自己想放的路径下,每个人的 style 都不一样,证书没有统一管理。
一旦人员流动,他做的这些事情就烂在生产环境了,所以出现很多证书没有及时续期和更新证书产生的故障。
我们痛定思痛之后,对全网的域名推动上 STGW,所有证书统一部署在 STGW 平台,申请、续期、更新等操作全部由组件运维团队来做。
证书通过域名一个一个的去扫描是否过期的可靠性就比较低,如果是 STGW 托管,我们直接从服务器上读取证书的过期时间,这是不可能失误的,而且证书安装更新的环境更加纯净,变更风险小了很多。
巨人的肩膀:织云路由
织云路由的定位是内网的名字服务系统。它是我们的用户请求经过 TGW 到内网之后,从接入层到逻辑层,逻辑层到存储层的寻址系统。
有一些企业在内网负载均衡也会用 F5,我们为什么不用呢?是差钱吗?我们根本不差钱。
我们为什么不用?因为我们的路由是强嵌入式的,对用户主调是有要求的。
这里有两个函数,接口非常简单,首先通过 GetRoute 获取 IP 端口,之后去访问,然后你访问我是成功还是失败,通过对 API Route Result Update 上报,对上报数据进行统计之后,做一个负载均衡的决策。
我们的织云路由跟业界大家熟知的组件到底有什么区别?刚才说了,我们不差钱,为什么要用织云路由呢?因为我们对服务的精细化治理有要求,所以它本身是一套服务精细化治理的解决方案。
它唯一的劣势是在使用门槛方面需要业务调用 API 代码,但是这也带来了好处。
相对 F5 和 LVS 这种无侵入的方式,基于调用方上报织云路由实现了后台服务质量的精细化管理,织云路由的成功率是 SNG 后台服务质量的考核标准,通过这个推动后台服务的质量。
二是负载均衡,根据业务上报的成功率设置了过载保护的能力,后台能力不行的时候会把多余的请求拒绝掉,只给能够成功的请求。
与其把请求全部发送给后端,把后端压死,不如在前端获取IP+端口的时候就告诉你过载了、不要请求了,把请求控制在后端能够承受的极限来发。
三是容错能力,F5 和 LVS 的容错只能探测到端口的连通性,而织云路由可以自定义容错场景。
四是相比 F5 和 LVS 的四层代理,对于被调服务获取主调 IP 会有很大的困难,对服务问题追踪是一个很大的门槛,而织云路由不会造成这种困扰。
巨人的肩膀:逻辑层统一框架 SPP
后台框架对运维的意义重大,SPP 由Proxy、Worker 和 Controller 三部分组成。
开发可以很简单就写一个鲁棒性强的高大上后台 Server,Controller 对 Worker 和 Proxy 有监控能力。
如果发现 Worker 和 Proxy 有问题会重新拉起,还可以通过配置 Worker 的进程数来控制程序的并发能力。
统一框架对运维的意义:
可以跨业务实现维护策略的统一。
#p#分页标题#e#网络框架和业务逻辑 SO 分离管理,运维具备快速升级框架的能力。有很多统一框架是集成的,和业务程序包打在一起、编译进去的,当框架推出一个新的优化,想全网快速普及的时候,要让所有业务系统重新编译发布。
而我们的框架和 SO 分离的管理方式,框架是由运维统一部署的,SO 是由业务部署的。框架有一个好的特性或者紧急的 Bug 要升级的时候,运维可以快速升级框架,不需要重新编译就可以做到这一点。
运维专业度提升。大家知道,铁打的业务,流水的兵,人员流动是非常快的。
我们统一框架之后可以做到运维在问题定位方面具备更强的能力,专业度的提升非常大,框架数据包的流转流程非常清楚,运维就比开发更懂他写的这个程序,当然除了业务逻辑除外,大部分方面运维比开发更专业。
Controller 对 Proxy 和 Worker 具备监控和起停的能力。C 语言后台程序经常出现 coredump,指针使用不善就会 core 掉,Controller 使 Worker 进程即使挂调也能够快速恢复。
运维实践中总结的几个原则
说完了巨人的肩膀,接下来说一下踮起脚尖一米八的眺望。如何让运维变得更加高效?
名字服务原则
前面说了,名字服务非常关键,我们要保证系统任何一个寻址都有名字服务。我们每年有上万台设备裁撤,没有 IP 是不能动的,所有 IP 都是可以变的。
近 10 万台设备,每天几台设备宕机成为一个常态,名字服务和容错是自动化运维的基础之一,重要性我前面也讲了很多。那么这里我分享一下运维是如何去影响研发侧,把名字服务的原则落实的。
我们从三方面来做:
联合 QA 建立质量考核体系。我们把访问关系梳理好,和名字服务的访问关系来对比,发现哪些调用没有使用名字服务,从名字服务的覆盖率和 QA 推动所有研发必须用。这是中策,毕竟推动也不是那么容易。
后台框架支持 RPC,封装路由寻址调用,让主调方在不知不觉中已经使用了名字服务,服务提供方就可以具备流量快速切换的能力。
拓展名字服务的场景,织云路由支持按照 UIN 的有状态寻址和一致性 hash 寻址,同时支持了 DNS 协议,降低接入门槛,这样来普及我们的名字服务。
一致性原则
我们 SNG 的服务是按照模块管理的,包括织云 CMDB 模块录入包、名字 ID、配置文件、权限等资源。你要看录入的资源和现网使用的是不是一样的。
所以我们运营的时候也遇到过一致性的问题,我们对装包的权限进行了收拢,由组件运维这边统一控制。
为了实现模块下所有设备包的一致性管理,不能有的机器装了、有的机器没有装,这会对现网带来运营风险。
配置文件方面,你通过配置系统发送到现网,有人篡改了,系统登记的和现网使用的配置不一致,只要你动这个配置就会出现问题。
所以我们正在启动一个改造,开启强一致功能,把现网机器上的配置文件和配置中心的进行一致性对比,发现不一致就强制修改回来。
同时,我们在想,配置管理为什么要以文件的方式,而不能以 Key-value 这种内存键值对呢?
使用 Key-value,你不需要在本地文件进行读取,有一些是服务热重启的,有一些不支持。
#p#分页标题#e#配置文件变更重启难免就会有影响,Key-value 的模式天然的就是不需要重启的,这种方案也有很多实现。我们后续主推 Key-value 的方式,让生效时间和影响都变得最优。
权限方面,最开始我们按照 IP 去管理,后来发现 IP 模块归属变化之后带来冗余,而且每次扩容都需要对新 IP 单独申请权限,短板很大。
所以我们就跟模块绑定,不是跟 IP 绑定,按照模块管理,只要在这个模块下就有这个权限,这个管理比 IP 管理要优一些。
某种程度上,我们织云按照模块的管理维度,你这个模块绑定了哪些名字,这个模块的 IP 是不是接入这些服务,如果有的没有接、有的接了,对于你缩容的时候会产生风险,会有把某一个名字踢空的风险。
所以我们定期进行比对,一旦发现有问题就派单去处理,保持模块下 IP 和服务接入名字两者的一致性。
无数据原则
这个原则是很重要的,对于我们接入和逻辑层,一个人维护 2 万台设备是非常关键的基础。我们要求所有的接入层和逻辑层设备无数据。
首先对于上报超时这种假死状态的告警,因为它无数据,所以整个处理过程变得很简单,需要考虑的点比较少,有告警我们首先判断是不是接入层和逻辑层设备,如果是就可以直接重启。
刚刚说了,我们的织云路由是具备流量自动恢复的,会在设备故障之后发现端口连通性恢复之后就把流量自动恢复过来。
如果重启不能修复就看驻场能不能修复,如果驻场不能修复就退役了,如果驻场能够修复就可以继续服务,这种就是简单粗暴可靠的。
第二个无数据还带来设备要求的简化,无 raid,硬盘故障之后直接换盘重装。
第三个无数据的要求,磁盘在保存尽可能多日志的前提下实现自动化清理。
我们一步一步的缩短日志保存的时间,直到磁盘不告警为止,对我们来说骚扰就会变得非常少。
统一原则
我们有统一后台框架、统一名字服务、统一配置中心、统一数据上报通道、统一包发布系统。
这些是自动化平台的基础,因为统一带来维护对象的减少和对上层调用系统呈现出来的简单,可以大大提升上层自动化系统的可靠性。
我们有一句话,不要在沙盘上建高楼,底子没有打好,自动化程度很难提升上来。
支撑大型活动事件的实战技巧
针对社交业务的活动、节假日做的事情,是比较个性化的,我们大型活动面临的挑战:扩容设备量大、模块多、扩容状态跟进难。
一个人要扩容一个模块还好,要扩容几十、上百个模块,你会发现流程状态跟进很难。
留给扩容部署的时间也紧,刚刚过去的 2018 年春节和红包活动,组件运维团队扩容 641 次,涉及 535 个模块,15701 台设备,扩容操作要求在设备交付后一周内完成。
看一下春节扩容的大概流程:首先是资源申请,要进行资源合理性 PK,然后要去采购,进行资源交付。
之后要有虚拟化的过程,设备生产和扩容部署在织云,验证灰度和全量上线涉及到织云路由(通过织云路由调度流量)和监控系统(通过监控系统查看新扩容 IP 的服务质量)。
活动搞完了,要下线,要进行设备隔离,整个资源的退还要在资源管理系统去做。我们面临和不同部门各个团队的沟通,各个系统单独操作的成本是很大的。
打一个简单的比方,当你有 15000 台设备分配下来的时候,你要把它划到对应的模块,这个事情如果不用工具去做,人肉去操作都要搞两三天,而且还很容易出错。
织云对于单个服务的自动化部署有四个流程:
部署准备,检查一致性、检查设备连通性、获取资源、屏蔽警告。
发布部署,申请权限、安装程序包、发配置、同步文件。
发布自检,启动软件包、进程端口扫描、治行测试工具。
灰度上线,一台灰度 10%,调用变更体检,全量接入。
我们比较好的具备单个服务的自动化部署能力,但是对于我们应对几百个模块的同时扩容还不够。
#p#分页标题#e#在这个基础上,我们做了批量部署的系统,各个系统对其功能对外都有接口化的能力,对外提供 http 接口,那么批量系统可以把各个系统的这些操作串联起来。
批量部署系统:
集中展示和管理,各个步骤封装成原子接口,在统一界面操作。
对接各个系统,比如说哪个模块扩容多少,在资源申请单的时候这是录入了的。批量系统根据资源申请单自动生产设备,把设备分配给相应的模块,批量在织云上发起扩容流程。
规模效应,批量操作上百个业务模块。
状态自动跟进,我们把关键节点的状态全部记录下来,在统一的页面上去展现,才知道这几百个模块扩容状态到底是什么样的,完成了多少,有哪些正在进行中、哪些失败了,便于聚焦扩容出现了问题的模块。
我们最终做到的效果就是能够在一周内把 15701 台设备 600 多次扩容全部搞定。春节期间的组件团队单人最多的时候运维超过 2 万台设备。
张黎明,SNG 组件运维团队负责人,有八年的运维经验。参与了国内社交平台 QQ、Qzone发展壮大到成熟的过程,也参与了 SNG 系统标准化、大规模组件运营推广,自动化运维等项目,在海量服务运维方面有一定的心得,所以今天给大家分享一下具体实战。
【编辑推荐】
阿里千亿交易背后,运维如何做到“0”故障发布?
运维的苦,谁懂?一次“心惊肉跳”的迁库经历!(有彩蛋)
一位女运维的自述:3年为公司节省10亿元!
运维不背锅!持续两年数据库“0故障”的运维优化之道
无服务器架构下的运维实践