写点什么

OPPO Monitor Platform:从应用请求到后端处理,自研解决服务化架构系统监控难题

  • 2015-11-06
  • 本文字数:6209 字

    阅读完需:约 20 分钟

众所周知,系统监控一直是拥有复杂 IT 架构的企业所面临的一个重要问题,而这也并不是每家企业都能够轻松解决的技术挑战。OPPO 作为一家国际智能终端设备及移动互联网服务供应商,推出过多款外观精细、功能可靠的智能手机产品,其品牌知名度也一直名列前茅。但实际上 OPPO 公司与其他快速发展的现代企业一样面临着自己的 IT 挑战,而更加鲜为人知的,则是其品牌背后同样出色的 IT 团队与信息化支持能力。

OPPO 后端系统规模近几年快速发展,系统重构以后采用了服务化的架构,各系统之间耦合降低,开发效率得到了很大的提升。然而在服务化带来了好处的同时,难于监控的问题也一并出现。由于服务之间调用关系错综复杂,接口出现问题,多个系统报错,因此很难定位真正的故障源头。整个请求调用链就像一个黑盒子,无法跟踪请求的整个调用路径,发现性能瓶颈点。

为了解决这些问题,OPPO 公司自行开发了一套监控系统,并结合第三方监控系统,形成了从 App 请求开始到后端处理过程的完整监控体系。OPPO 监控系统的简称为 OMP(OPPO Monitor Platform),历时半年开发,分为两期上线,现在已全面接入 OPPO 线上项目。

三大理由决定自主研发

之所以选择自主研发监控系统,主要是考虑到三方面的原因:定制化需求、易用性、以及开发成本低。

首先,在对比之后发现现有的开源监控软件无法满足 OPPO 的需求。对于监控系统来说最核心的一条需求,就是要能够监控每个 App 请求的完整调用链,从 App 发起请求,到后端的负载均衡接入、API Server、微服务调用、缓存、消息队列、数据库访问时间等。系统架构微服务化以后,服务跟踪和服务调用链监控尤为重要,否则系统故障及性能瓶颈就很难排查了。

为了打通用户请求的完整调用链,需要在 API 框架、RPC 框架、缓存操作、数据库操作、队列消费等代码埋点,以及高性能处理和存储系统,而目前的开源软件无法满足需求,各大公司也因此才开发了自己的监控平台。由于服务调用跟踪功能跟开发框架深度关联,各公司选用的框架并不相同,所以业界鲜有类似开源的产品。

第二个原因是考虑到权限及一体化管理界面的需求。监控平台不仅仅面向运维人员,开发人员、运营人员、测试人员也需要经常使用。例如根据监控平台采集到 JVM Young GC/Full GC 次数及时间、耗时 Top 10 线程堆栈等信息,经常查看监控平台,开发、测试人员便可以评估代码质量,排除隐患。

监控平台面向用户众多,安全性及权限管理要求较高,同时需要一体化的管理界面,简洁易用,而组合多个开源软件,权限和管理便捷性很难满足需求。

第三,监控系统的开发难度比较低。自行研发的监控平台虽有千般好处,但是如果开发的难度太大,以至于无法持续的投入,那也是没有意义的。基于 Sigar、kafka、Flume、HBase、Netty 等技术,开发高性能、可伸缩的系统难度实际上并不大,需要投入的资源不需要很多。

六项目标内容实现线上应用全面监控

OMP 的最终目标是提供一体化的监控系统,在同一套管理界面及权限体系之下,对线上应用系统进行多维度的监控。OMP 现阶段主要监控内容包括:主机性能指标监控、中间件性能指标监控、服务调用链实时监控、接口性能指标监控、日志实时监控、业务指标实时监控。

主机性能指标监控方面的开源软件非常多,比如 Zabbix、Cacti 等。主要采集主机的 CPU 负载、内存使用率、各网卡的上下行流量、各磁盘读写速率、各磁盘读写次数 (IOPS)、各磁盘空间使用率等。

借助开源的 Sigar 库,可以轻松采集主机信息,为了保证整个监控系统体验的一致性,以及系统扩展性、稳定性的要求,我们没有直接采用 Zabbix 等开源监控系统,而是自己开发 Agent 程序,部署在主机上采集信息。

Sigar(System Information Gatherer And Reporter),是一个开源的工具,提供了跨平台的系统信息收集的 API。核心由 C 语言实现的,可以被以下语言调用: C/C++、Java 、Perl 、NET C# 、Ruby 、Python 、PHP 、Erlang 。

Sigar 可以收集的信息包括:

1) CPU 信息,包括基本信息(vendor、model、mhz、cacheSize)和统计信息(user、sys、idle、nice、wait)

2) 文件系统信息,包括 Filesystem、Size、Used、Avail、Use%、Type

3) 事件信息,类似 Service Control Manager

4) 内存信息,物理内存和交换内存的总数、使用数、剩余数;RAM 的大小

5) 网络信息,包括网络接口信息和网络路由信息

6) 进程信息,包括每个进程的内存、CPU 占用数、状态、参数、句柄

7)IO 信息,包括 IO 的状态,读写大小等

8) 服务状态信息

9) 系统信息,包括操作系统版本,系统资源限制情况,系统运行时间以及负载,JAVA 的版本信息等.

对于中间件性能指标监控,目前根据业务使用中间件的情况来看,主要采集的中间件包括 Nginx、MySQL、MongoDB、Redis、Memcached、JVM、Kafka 等。实现方式为部署独立的采集服务器,通过中间件的 java 客户端执行状态查询命令,解析出相应的性能指标,采集的部分指标如下表所示:

JVM

堆内存、永久代内存、老年代内存、线程 CPU 时间、线程堆栈、Yong GC、Full GC

MySQL

慢查询、QPS、TPS、连接数、空间大小、表锁、行锁…

Redis

QPS、命中率、连接数、条目数、占用内存…

Memcached

QPS、命中率、占用内存、条目数、连接数…

Nginx

每秒请求数、连接数、keepalive 连接数、持久连接利用率…

系统架构微服务化以后,服务调用错综复杂,出了问题或性能瓶颈,往往很难定位。所以服务调用链实时监控极为重要。

服务调用链监控是从一个 App 发起请求开始,分析各环节耗时及错误情况,包括负载均衡接入、API Server 耗时、微服务调用耗时、缓存访问耗时、数据库访问耗时、消息队列处理耗时等,以及各环节的错误信息,便于跟踪性能瓶颈及错误。

由于服务调用量巨大,同时便于管理员查看,监控系统不能存储所有请求的调用链,主要存储以下几种请求:

1) 周期内最慢 Top 1000 请求:通过分析最慢的 top 1000 请求,可以判断主要的性能瓶颈环节,比如数据库访问,或者调用第三方公司接口耗时过多。

2) 采样请求:根据设置采样比例,随机选取部分请求,存储请求的调用链。

3) 关键字:满足关键字规则,存储请求的调用链。

接口性能指标监控,主要监控接口的可用性和响应时间,由内部监控和外部监控两部分组成。

1) 外部监控:外部监控由第三方公司负责,分为两种,一是 App 中埋点,采集真实的业务请求性能指标。二是通过第三方公司部署在各地的采集点,主动监控接口在各地区的可用性和性能指标。

外部监控只能监控负载均衡器对外的最终接口服务地址的可用性和性能指标,如果要监控机房内部接口服务器,则需要机房内部部署第三方公司的 Agent,这样会带来非常大安全风险,所以机房内部节点监控由内部监控完成。

2) 内部监控:内部监控采用 OMP,监控负载均衡层后面的接口服务器的可用性和性能指标,及时发现异常节点,同时 OMP 根据异常原因,回调业务系统提供的恢复 URL,尝试恢复系统。

应用产生的日志分散在各应用服务器当中,由于安全管理非常严格,开发人员查看线上系统的日志非常不方便,同时日志内容匹配关键字需要发送告警通知相关人员。OMP 将日志统一采集存储到 Elastic Search 集群,实现日志检索。OMP日志实时监控主要包括如下功能:

1) 日志实时在线查看:监控平台可以实时查看日志文件的内容,效果类似 tail –f 命令,同时屏蔽内容中的敏感信息(如密码等)。

2) 日志全文检索:全文检索日志内容及高亮显示

3) 关联日志查看:查看日志产生时刻,日志所属应用关联组件和应用的日志

4) 关键字告警:用户自己定义告警规则,符合匹配规则发送邮件和短信通知。

最后一项监控内容,是业务指标实时监控。除了监控系统主动采集的信息,还有业务层指标需要进行监控,如周期内订单数量、第三方数据同步结果等。这些业务层的指标数据,由各业务系统负责采集,然后上报到监控系统,监控系统完成图表展现及告警通知。

四大方面详解 OPM 系统设计

首先来了解一下 OPM 的系统体系架构,如下图所示:

(点击放大图像)

1) 中间件采集器:独立部署多台中间件性能指标采集器,通过 Zookeeper 实现故障转移和任务分配。中间件采集器通过中间件的 Java 客户端执行状态查询命令,解析命令结果得到性能指标,由于状态查询得到的是最新累计值,采集器还负责计算周期内的均值、最大值、最小值等周期数据。中间件采集将采集到的数据实时上报到接收器集群。

2) Agent 监控代理:Agent 监控代理部署在各服务器上,实时采集服务器的日志文件内容、CPU 负载、内存使用率、网卡上下行流量、磁盘读写速率、磁盘读写次数 (IOPS) 等。Agent 采集到的数据实时上报到接收器集群,对于日志文件,为防止阻塞,上传过程还需要做流控和丢弃策略。

3) 代码埋点:代码埋点主要采集服务调用链数据,通过封装的缓存访问层、数据库访问层、消息队列访问层,以及分布式服务框架 (RPC),获得服务调用链耗时和错误信息。代码埋点采集数据本机暂存,一分钟合并上报一次到接收器集群。

4) 业务指标上报:业务指标由各业务系统负责采集,上报到接收器集群,上报周期和策略由各业务决定。

5) 接收器集群:OPPO 自研的 Data Flow 组件,架构参考 Flume,内部包括输入、通道、输出三部分,将接收到的数据输出到 Kafka 队列,后文将作详细介绍。

6) Kafka 消息队列:由于监控数据允许丢失和重复消费,所以选择高性能的 Kafka 做为消息队列,缓冲消息处理。

7) 消息处理集群:消息处理集群订阅 Kafka 主题,并行处理消息,处理告警规则、发送通知、存储到 HBase 和 ES。

8) Hbase:HBase 存储指标类数据,管理控制台通过查询 HBase 生成实时图表。

9) Elastic Search:存储日志内容,实现日志全文检索。

(点击放大图像)

OPPO Data Flow实现了数据流配置和管理,设计参考 Flume,内部包括 Source(输入)、通道 (Channel)、输出 (Sink) 三部分,通道是一个队列,具备缓冲数据的功能。之所以不采用 Flume,主要考虑如下几个原因:

1) Flume 提供了良好的 SourceàchannelàSink 框架,但具体的 Source、Sink 需要自己去实现,以兼容 oppo 线上使用软件版本,以及优化的参数配置。

2) Flume 资源占用较大,不适合作为 Agent 部署在业务服务器上

3) Flume 配置文件采用 properties 方式,不如 xml 配置直观,更不能管理界面来配置

4) Flume 管理界面不友好,不能查看输入、输出的实时流量图表以及错误数量。

参考 Flume 的设计思想,OPPO Data Flow 是更易管理、配置更便捷的数据流工具。使用开源软件,并不只是拿来就用这一种方式,学习其设计精华,从而进一步改进也是一种方式。

实际上,Agent 监控代理、中间件采集器、接收器集群都是 OPPO Data Flow 组件,组合不同的 Source 和 Sink。Source、Sink 采用 OSF 服务框架开发,实现 Agentà接收器的自动发现、负载均衡及故障转移功能。

输入 (Source)

通道 (Channel)

输出 (Sink)

Agent 监控代理

TailFileSource

CPUSource

MemorySource

NetworkSource

DiskSource

MemoryChannel

HttpSink

中间件采集器

NginxSource

MySqlSource

MongoDBSource

RedisSource

JvmSource

MemcachedSource

MemoryChannel

HttpSink

接收器

HttpSource

FileChannel

KafkaSink

下图为 Data Flow 内嵌管理界面,可以查看数据流量和错误信息,点击名称可以查看历史流量。

(点击放大图像)

服务调用链是监控的重点,核心的核心,为了打通服务调用链,OPPO 开发了OSF(OPPO Service Framework)分布式服务框架,并对缓存、数据库、消息队列操作进行封装埋点,目的是透明的实现服务调用跟踪。实现方式如下:

1) 在 App 请求的入口生成唯一 requestID,放入 ThreadLocal

2) 缓存访问层代码埋点,从 ThradLocal 取出 requestID,记录缓存操作耗时

3) 数据库访问层代码埋点,从 ThradLocal 取出 requestID,记录数据库操作耗时

4) 调用其它微服务 (RPC),将 requestID 传递到下一个微服务,微服务将接收到的 requestID 存入 ThreadLocal,微服务内部的缓存、数据库操作同样记录 requestID 操作耗时及错误信息。

5) 消息队列写入、消费代码埋点,传递 requestID,记录消息消费耗时。

调用链数据庞大,无法全量存储,监控系统将周期内最慢 Top1000 请求,采样的部分请求以及符合关键字规则请求的服务调用链存储在 HBase 中,管理控制台可以快速分析查看。

分布式服务框架是打通服务调用链的关键。开源的 Dubbo 应用广泛,考虑到 Dubbo 版本较长时间没有更新(有些 Dubbo 依赖库已经跟开发生态的其他开源组件版本冲突)、代码量较大,而且服务治理能力较弱,很难完全掌控 Dubbo 的所有细节,而前文提到的 OPPO 自行开发的分布式服务框架 OSF,代码精简满足核心需求,与监控系统深度集成。

OSF 实现微服务 RPC 调用 requestID 的传递,记录每个服务的调用耗时及错误信息,框架每分钟汇总上报微服务调用耗时及错误信息到监控平台。

OSF 主要特性如下:

1) 支持 RESTFul 协议,容器支持 Tomcat、Netty、JDK Http Server

2) 支持 TCP 二进制协议,容器支持 Netty

3) 支持 HTTP/2 协议,测试中

4) 支持 Protobuf、JProtobuf、Kryo、FST、MessagePack、Jackson、GSON、Hessian 序列化实现

由消费方决定序列化方式

5) 注册中心基于 MySQL,同时提供推送、client 拉取两种方式,保证服务发现可靠性。

6) 注册中心提供 HTTP API,支持多语言、移动设备

7) 支持多数据中心部署

8) I/O 线程与工作线程池分离,提供方忙时立即响应 client 重试其它节点

(点击放大图像)

可靠性及伸缩性角度来看,主要包括以下内容:

1) 接收器:接收器的输入采用 OSF RESTFul 协议开发,通过注册中心,client 能够自动发现接收器节点的变化,通过 client 实现负载均衡及故障转移,从而保证接收器的可靠性、伸缩性。

2) 中间件采集器:中间件采集器通过 zookeeper 选举 Master,由 Mater 来分配采集任务,采集器节点变化,选举的 Master 重新分配采集任务,这样任意增减采集器节点,都能重新平衡采集任务,保证采集任务的持续可靠运行。

3) 消息处理:由于多个节点均分同一个 kafka topic 的消息并且实现高可用比较困难,OMP 预先定义了若干个 kafka topic,消息处理节点通过 zookeeper 选举 Master,由 Master 来分配 Topic 数量,当某个消息处理节点宕机,该节点负责的 topic 转移到其他节点继续处理。

4) Agent 监控代理:服务器上 shell 脚本定期检查 Agent 状态,不可用时自动重启 Agent,同时 OMP 维持与 Agent 之间的心跳消息,超过 3 个周期没有收到 Agent 的心跳消息,OMP 发送告警通知相关人员处理。

从 OPPO 的自主研发监控系统的实践案例来看,一切应当从业务需求出发,目的是解决业务遇到的问题。面对开源软件的选择,要有所“为”,有所“不为”。业界有很多成熟的开源软件,也有一些比较大胆的设计思想可供借鉴,但开源软件并不是拿过来就能用好这么简单的,选择的原则可“管”可“控”。一个开源软件,如果不能“掌控”,不够简单,那就不如不用,自己用土办法也许反而会更好,出了问题至少还能想想应急的办法。同样要具备“管理”性,不然黑盒子般运行,心里没底,那作为 IT 管理人员来说就睡不安心了。

作者简介

罗代均,现就职于 OPPO 基础技术团队,从事监控平台、服务框架等基础技术开发工作。2005 年毕业后,先后主导过通信、移动金融、应用商店、PaaS 平台等领域多个产品系统设计开发、项目管理工作。


感谢刘羽飞对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-11-06 03:168428

评论

发布
暂无评论
发现更多内容

加速国产开源软件创新,云智慧AIOps社区正式发布

云智慧AIOps社区

开源 算法 数据 场景 智能运维

基于深度学习的日志异常检测

云智慧AIOps社区

深度学习 招聘 异常检测 实习 智能运维

这个 TCP 问题你得懂:Cannot assign requested address

AlwaysBeta

Linux TCP TCP/IP Linux内核 TCP协议

女科学家流失之殇

脑极体

无场景不智能-面向场景的智能运维算法体系

云智慧AIOps社区

算法 日志 场景 智能运维 数据指标

TLS协议分析 (六) handshake协议扩展

OpenIM

【布道API】关于 API 分页

devpoint

API REST API 9月日更

GitHub上标星120K!Alibaba官网发布了这份Java全栈知识体系手册

Java~~~

Java 架构 面试 JVM 多线程

27W字总结阿里Java高并发编程:案例+源码+面试+系统架构设计

Java~~~

Java 架构 面试 算法 多线程

交易所刷量机器人定制开发,刷k线机器人搭建

量化系统19942438797

交易所 市值机器人

CTO离职前悄悄和我说,吃透这5本Java核心技术笔记,涨薪特别简单

Java~~~

Java MySQL spring 架构 面试

云智慧智能研究院实习生招聘信息~只等优秀的你!

云智慧AIOps社区

深度学习 招聘 异常检测 实习 智能运维

Java设计模式如何优雅的使用本地缓存?

张音乐

Java 缓存 9月日更

谈 C++17 里的 FlyWeight 模式

hedzr

c++ 设计模式 Design Patterns 享元模式 flyweight

【架构设计模块七】:王者荣耀商城异地多活架构设计

Ryoma

阿里内部流传的JDK源码剖析手册!GitHub已获上千万的访问量

Java 编程 架构 jdk 面试

云智慧AIOps研究院来咯~

云智慧AIOps社区

技术 算法 数据 智能运维 指标

机器学题平台PAI论文入选国际顶会KDD-构建端到端的大规模AI工程能力

阿里云大数据AI技术

“IBP在城市大脑项目中的应用”入选工信部2021年大数据产业发展试点示范项目名单

云计算

10款低/无代码开发平台哪个才是适合你的?

低代码小观

程序员 低代码 无代码 低代码平台 无代码平台

职场浅谈三则

姬翔

9月日更

【网络安全】记一次挖洞的日常

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

无敌!阿里巴巴开源落地可实操项目:网约车+咚宝商城+英雄传说

Java~~~

Java 架构 面试 项目 架构师

Filecoin价格今日走势:filecoin暴涨!Filecoin未来会涨到多少钱?

区块链 分布式存储 filecoin未来价格预测? filecoin价格走势 filecoin大涨

TLS协议分析 (七) 安全性分析

OpenIM

阿里P8整理出SQL笔记:收获不止SOL优化抓住SQL的本质,带你领略SQL的世界!

Java MySQL 架构 面试 架构师

GAIA:智能运维领域通用公开数据集

云智慧AIOps社区

算法 AIOPS 数据集 场景 智能运维

pyhanlp 添加自定义词典(qbit)

qbit

Python nlp 分词

如何让项目准时上线?

石云升

项目管理 管理 引航计划 内容合集 9月日更

Kubernetes踩坑问题集

玏佾

Kubernetes k8s k8s文档

Navicat Premium 查询 x 列时不显示

玄兴梦影

MySQL navicat select

OPPO Monitor Platform:从应用请求到后端处理,自研解决服务化架构系统监控难题_架构_罗代均_InfoQ精选文章