华为吴晟:分布式监控系统的设计与实现

  • 郭蕾

2017 年 8 月 14 日

话题:DevOps语言 & 开发APM运维

微服务架构其实就是将单一的应用程序划分成为一组小的服务,其中每个服务都是独立的业务单元,同时又能够被独立开发、运行、测试以及部署。简单来说,它的本质其实就是拆分和独立,这也决定了微服务的部署应该是分布式的。微服务架构虽然解决了目前诸多的架构层面的问题,但在分布式部署的环境中,如何才能够有效监控每一个服务,并及时发现系统中的问题又成为了新的挑战。

Google 公司早已就在其生产系统中实践了分布式理念,为了解决监控问题,他们研发了 Dapper 分布式跟踪系统,并对外公开了相关论文。与此同时,Twitter 基于 Google 的论文开发了 Dapper 系统的开源实现Zipkin。国内类似的有过曝光的系统还有淘宝鹰眼系统 EagleEye 以及开源软件 Skywalking。InfoQ 记者就分布式监控相关的问题采访了 Skywalking 作者吴晟,请他从整体层面为读者分享解读分布式监控相关的技术难点。另外,吴晟也将会在 9 月 10 日举行的CNUTCon 全球运维技术大会上分享相关话题,欢迎关注。

InfoQ:对于分布式系统的监控,你认为难点是什么?目前有哪些可行的落地思路?

吴晟:分布式监控系统从使用的角度上,无论是手动探针还是自动探针,上手难度都不大。多数的技术型软件,从数据库、大数据处理到流式计算,在入门时都需要经历复杂的安装和参数设置过程。但是对于分布式监控系统,无论是 Zipkin、Skywalking 这些国内外的开源监控产品,还是各种商业 APM 产品,安装和入门难度都不大。

但对于开发一款分布式监控系统来说,情境则完全不同,无论是探针还是后台处理都有很多的挑战。比如:

  • Java 自动探针的实现,对于 Java 字节码、程序运行情况、GC、程序优化都要有相当细致的要求。

  • 后端分析服务,如果不了解探针,给出的分析方案难度大,效率低,机器需求量大。

  • 探针网络传输的需求,序列化效率。

在 APM 领域,程序的细节决定产品的性能。目前按照探针的实现,可行的思路主要有四种:

  1. 基于日志系统,探针只负责对日志加上编号,又类似 ELK 的系统进行收集、处理、展示。这方面没有很成熟的产品,一般都属于公司内部封装的框架。

  2. 自动探针,适用语言:Java、C#、PHP、Node.js 等等存在 VM 的语言。绝对大多数的商业产品和热门的开源产品都属于这个系列。

  3. 全手动探针,优势是适用范围广,最有名的就是 Zipkin 的整个生态系统,分布式追踪几乎无处不在。也是现在全球运用最广泛的分布式监控系统。

  4. 同时支持自动和手动模式的探针,适用语言同样是 Java、C#、PHP、Node.js 等等存在 VM 的语言,由于技术复杂性提高,运用的较少。优点是入门方便,同时使用灵活。商业上主要是 Instana,开源主要是 sky-walking 提供了技术解决方案。

InfoQ:分布式监控领域常用的理论都有哪些?

吴晟:所有的分布式理论几乎都来自 2010 年的 Google 论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,这里面详尽的描述了分布式系统的解决思路。

Dapper 作为分布式监控的核心,主要给大家介绍了 Trace、Span、spanId、log、采样等几个重要概念。其中 Trace 就是一个可能跨越多个节点的分布式。Span 是调用过程中一个时间区间(时间跨度),这也是这个英文名字的由来。一般对应一个方法或者代码块的执行。SpanId 按照书的索引方式(例如 1, 1.0, 1.1, 1.1.1)来表达层级关系,让更多的读者很好的理解了调用链追踪。不过这里要强调的是,绝大多数的追踪系统,包括开源和商业,在工程实践上,因为消耗问题都放弃了这种方法。

log 是 Span 跨度内发生的事件,比如异常。在实际的产品中,会使用 Tag、Annotation、Log、Event 等多种概念来提升效率。采样是 Dapper 是大篇幅强调的问题,也就是说,超高并发系统中采样是必然,如何采样也是各产品策略不同,比如按照 Span 采样,按照 Trace 采样。

但是几乎所有的现在开源和商业分布式监控系统,都在论文的基础上做了大量改进,模型并不相同。目前阶段,CNCF 基金会的 OpenTracing 标准,是一个很好的理论参考。

还有就是 Zipkin 的庞大生态和大量公司的参与。我和 Zipkin 的负责人,Pivotal 资深工程师 Adrian Cole 有过很多的沟通,在跨语言,跨平台的监控上,Zipkin 有着强大的用户基础和案例。

InfoQ:从你的角度来看,分布式监控系统应该包含哪些模块?

吴晟:监控系统一般分为三大模块:

探针或 SDK,负责数据采集和发送。探针或 SDK 是应用程序的收集端。一般使用插件的模式,自动探针一般是不需要修改程序,而 SDK 则是需要修改部分配置或者代码。skywalking 就是自动探针为主,zipkin-brave 就是 Zipkin 的 Java 手动探针。

Collector 模块,负责数据收集、分析、汇总、告警和存储。Collector 模块,这个根据不同的 APM 实现,可能由一个或者多个子系统构成。Collector 负责对探针和 SDK 提供网络接口(TCP、UDP、HTTP 不同形式接口)。

功能上,主要包含数据收集、分析、汇总、告警和存储。这些模块在复杂的开源 APM 和商业产品上都保持一致。大家选择时,值得注意的是,现在包括 Zipkin 在内的不少国外的追踪系统,是只负责追踪,不负责分析汇总,他们认为分析可以由使用者自己负责。

作为分析方式,分为流式分析和异步批量两种,而流式分析会对数据统计和告警的实时性更有帮助。

UI,负责高实时性的展现。包括但不限于 Trace 的查询,统计数据展现,拓扑图展现,VM 或进程相关信息等,监控关键数据的展现。

InfoQ:对于访问量较大的应用,如何解决埋点监控的性能问题?

吴晟:这是我在本次分享里面很多内容的根本,性能问题。这个其实没有标准答案,根据系统的不同,流量不同,容忍度不同,标准会完全不同。我们举个简单的例子,在 Google,千分之一,万分之一的采样,依然是大数据分析,依然足以定位问题;在多数非 BAT 核心产品上,50% 或者 100% 采样都不会有性能问题。一定要选择适合自己的,不要过分担忧。

一般说来,一款合格的产品,在单点 500TPS 之下的应用,采样率都可以保持的很高。

InfoQ:现在你们的监控系统有没有结合大数据分析,智能的进行故障预警以及处理?

吴晟:目前 sky-walking 没有去做这方面的工作,因为这样会大大增加部署和运维的难度。有需求,有运维的能力的公司,很容易在产品的基础上进行相关的分析。

在商业产品中,指标方差数,趋势分析,偏移量,热度分析,用户促销活动等等都是在处理范围中。

InfoQ:你的演讲里有一个有趣的观点,面向研发的监控和面向运维的监控,如何理解这句话?

吴晟:虽然现在 DevOps 很热,但是无论一体化进行到哪个阶段,线上问题和开发迭代,永远都有时间差。所以“线上问题的发现、规避和应急响应”和“研发过程对于产品的改进和修复”是两个有联系又实际并不相同的理念。

目前的 DevOps,强调快速的迭代和响应,微更新,快速发布。相关的容器化技术也是倍受追捧。而这些对于分布式监控的要求也是越来越高。主要原因是分布式的节点,从几十个上升到几百个上千个都是很常见的。

但是,DevOps 的发展,并不会完全消除“线上问题响应”和”线下修复问题“中间的时间差。

比如在生产环境中,某个数据库因为冷门业务的某条大 SQL 语句缓慢,拖慢服务器 IO 性能,造成应用其他主要接口响应受到影响。

  1. 对于运维人员,监控系统的职责是需要发现这条慢 SQL,识别数据对应的 session 信息,辅助运维人员杀掉这条 SQL 的执行。

  2. 对于开发人员,则需要反馈调用链路,找到发生这条 SQL 调用的原因,是特定参数引起的,还是特定的条件分支,或者是特定的用户。并通过本周期迭代,避免或降低再次发生这个问题的风险。

这个案例中,你会看到,其实,APM 系统需要提供的信息是不太相同的。这就是所谓的“面向研发的监控”和“面向运维的监控”之间的差别。而很多人都忽略了这个差别,而这对于 APM 系统的运用和演进都是很重要的。

DevOps语言 & 开发APM运维