宜家的全球化采购和直销模式,能够取得如此巨大的成功,与宜家在创办初期,就确立的标准化设计理念有关。
在宜家,如果一个产品不能被扁平化包装运输,那么即使设计再精妙,也不会被批量生产。设计和运输同样重要!
坚持「可运输性」的设计理念,降低了产品到达终端用户的成本。便宜、快捷的体验,进一步推动着宜家的持续发展。
同样的,规模化的运维,不能再是见招拆招,追着业务满世界跑,应该全局统筹,将多变的业务需求抽象为高度统一的运维模型,通过平台来体系化的支撑。
我们希望能有这么一个标准化的魔法箱子,把我们的代码,打包进去,运行、维护、扩容、容灾都是流水线的方式自动化进行。
根据“熵理论”:
一个孤立的系统,始终会趋向于越来越乱(无序化)的方向发展。
如果要让一个系统变得更有序,必须有外部能量的输入。
所以对于我们动辄几千上万台的互联网行业来讲,加上特有的「快速试错」理念加持,这个庞大的、错综复杂的系统,总是倾向于越来越乱。
这就需要我们格外投入精力,才能让系统朝着有序的方向发展。
如果我们在设计或者开发阶段,欠下更多的债,埋下更多的坑,那么在产品的运行维护阶段,就要加倍偿还这些技术债务。
债总是在那里,只是在哪个阶段还的问题,systems do not run themselves。
规模化的互联网运维
经常会有人问,1个人支撑10台服务器和1个人支撑2000台服务器,到底哪个更难一些?
当运维支撑体系不完善,业务模块都不同构,监控方式、部署方式百花齐放,1个人要支撑10台服务器,就已经疲于应付,处于要崩溃的边缘了;
相反,如果所有的服务,都是同样的监控方式、部署方式,同时运维支持体系都是自动化的,那么1个人支撑2000台服务器,也是轻松加愉快的。
以滴滴为例,在四年时间里,从最初只有四台服务器,发展到现在的数万台设备,在这样的发展速度下,显然我们要采用规模化的运作方式,提高运维效率,自动化一切是摆在我们面前唯一的出路。
一切系统的设计,都是在满足一定假设前提下的产物,而自动化的前提,恰恰就是“标准化”。
总之,在一个统一的标准和实践引导下,所有人去尽可能靠拢,那么事情会变得简单很多!
所以,半年时间里,我们主要围绕着三个方面在推进服务标准化的事情:
配置管理
常见的配置包括以下一些内容:
上下游的连接信息,与环境的耦合度最高,是最复杂、最多变、最难处理的部分。
我们看看大家一般都是怎么来对付上下游连接信息的:
这种方案的好处就是充分利用了LVS的高可用特性以及负载均衡、健康检查能力,将上下游的耦合转移到LVS的配置中。
这样的坏处也显而易见,配置管理虽然集中化了,但是流量也集中化了,存在严重的单点风险。
这种该方案的优缺点,同LVS方案,只不过是工作在七层罢了。
这种方案负载均衡策略太单一,同时切换速度太慢。
这是非常经典的方案,成熟度较高,只不过在网络发生分区的时候容易出问题。
这是最原始的方案了,上下游的连接信息,直接写在模块的配置文件中,散落在目标服务器上。使得整个拓扑关系不清晰,故障切换速度慢。
针对这些现实情况,我们迫切需要建设配置管理,来解决:
此外,自动注册和发现,这些特性都可以在现有的基础上,方便的叠加。
对于运维的系统和基础设施建设,理念的一致性和延续性非常重要,当前的任何一个方案,都要充分考虑和未来三年的长远方向是否一致,今天所做的工作是否在为长远目标铺路。
最忌讳的情况就是后来的方案需要不停的推翻早先的方案,业务的改造成本是要重点考虑的。
监控
监控是整个运维环节,乃至整个产品生命周期中最重要的一环,事前及时预警发现故障,事后提供翔实的数据用于追查定位问题,分析业务指标等。
那么残酷的现实情况是怎样的呢?
这种方案,定制化程度高,维护成本高,试想想,过了三个月,面对你所配置的一大堆正则表达式规则,你有勇气去面对和维护吗?
同时在线分析日志,会对在线服务器造成较大的性能消耗。
该方案时效性较低,对日志的耦合高,同时大量日志的传输分析需要的资源消耗也是非常可观的,不够经济,不够轻量。
这种方式,理念已经较为先进了,研发在设计和开发模块的时候,就已经充分预见到了需要暴露哪些指标,来有效的监控自身的运行状态和各种统计信息。
但是一千个人眼里有一千个哈姆雷特,每位研发同学都有自己的见解,于是这些接口输出格式和意义各不相同,缺乏一致性的规范,在整体运维的层面,造成困难。
这种应该是最糟糕、最落后的方式了,研发在设计和开发模块的时候,没有一丝丝的“监控”意识,没有暴露自身的状态和信息,甚至也没有打印相关重要日志。
等到这样的代码上线后,才想起来,是不是需要加一些监控。
那么对于这些既成事实,受限于业务的压力,运维只能抛却原则和底线,无奈妥协,然后想尽各种旁门左道的办法,给业务模块写监控外挂。
这些外挂和每个模块自身特性紧密耦合,业务一不小心改了,监控外挂就得跟着改;同时如果每个业务模块都这么搞,基本上这些业务就处于事实上的“不可运维”状态了。
看完上面的几种情况分析,再一次说明,规模化的运维,不能是见招拆招,应该全局统筹。
针对监控,我们提炼了两条基本原则:
坚持业务指标采集是代码的一部分原则不动摇,提高指标覆盖率。
监控方式和指标要标准化,工具支撑系统化。
原则1,没有人比模块的研发人员,更清楚其工作机制,更关心其运行状态,模块自身的可运维性就是代码功能的重要组成部分。
每次业务逻辑部分的代码变更,都应该伴随着监控指标采集的相应更改。
有了原则1,还远远不够,没有好的工具和体系支撑,提高指标覆盖率就是一句空话。
在运维层面,应该制定统一的监控标准,推行统一的最佳实践,提供统一强大便捷的metrics lib库支撑。
这样才能更容易的推进自动化进程,以及更高的监控指标覆盖度。
谈谈监控标准化,标准如何定义?
1. 每个业务的每个接口,都要可被监控。
2. 每个接口的监控指标,必须至少包含:
cps
latency-50th/75th/95th/99th…
error_rate
error_count
3. 可以在2的基础上,扩充相关自定义指标,比如:
caller
callee
这样就可以细化到调用关系级别的数据。
4. 所有的指标上报,采用主动push机制,无需预先注册。
有了上面的一些标准化的指导思想,我们就可以着手开发lib库,推进业务模块接入了。
以nginx为例,监控指标采集,可以参考我们的实现:
http://book.open-falcon.org/zh/usage/ngx_metric.html 。
采集到的指标包括:
有了这些标准化的指标,很少的几个告警策略就能覆盖到绝大数的业务模块,而不用担心针对每个业务添加不同的告警策略。
同时可以针对每个业务,根据不同的用户,建立各自的dashboard,比如针对老板、研发、运维、测试,关注的dashboard侧重点都有所不同。
部署
说起来很简单,部署就是将代码、配置、数据,在一组资源上,保持给定数量的实例在运行。
但,现实是骨感的,存在着这样那样的痛点:
新业务接入沟通成本高
环境依赖多(PHP/java/golang/c++)
上下游连接信息管理乱(拓扑不明确,散落在各个目标服务器上)
用户体验不统一(编译打包、发单、审核、执行、观察各个环节脱节)
增量更新存在协同上的问题
部署和变更,我们的一些原则:
可以预见,经过坚持不懈的标准化改造,线上服务:
配置和环境解耦了
监控标准化了
部署规范化了
日志网络化了
数据service化了
实例自发现了
资源容器化了
全自动化调度,顺势而为罢了。
CIO之家 www.ciozj.com 公众号:imciow