做为一名合格的开发者不仅要懂得开发的内容,还要懂得业务监控的一些内容,下面是本人学习加上自己实践的情况总结的一些内容,主要包括传统监控和业务的立体监控的内容。
为什么需要监控
首先说监控的原因,所有的服务都具有不稳定性,我们监控进程状态,及时发现问题进行人工干预,从而掌握主动权。
监控对象
最基本的内容,我们监控的是进程的运行状态和机器的运行状态,除了最基本的内容,我们还要监控我们的业务运行情况。前者是通用的内容,后者是与业务有关的内容。
数据采集的方法
数据采集的方法通常分成几类:
1.用户请求的日志
用户请求的日志主要通过log日志打印的方式记录,这种方式是最基本的方式,现实系统中大多数也采用这种方式,如果日志的太大,基本就会产生大量的日志内容。
2.服务端数据上报
主要通过服务端采集业务数据上报,另外也可以对业务本身进行内容的统计监控,如多维度立体业务监控。
3.前端app产生的行为
有些业务场景无法通过服务端进行统计,如:用户在某个页面的时长,对于某个按钮的点击日志,feed博文的真实阅读等内容。这些都需要通过前端app进行日志记录的,然后通过专线的日志传输通道传递到服务端再进行处理。
日志的规范
各个公司采用的日志规范不一样,服务端,客户端,统计部门达成统一的协议,满足业务实际要求即可。我见过的系统中,有规定固定的字段,用`进行分割的,也有采用key=value 多个字段用空格分割的都可以。
传统服务的监控手段
传统互联网服务的监控手段主要包含以下几个方面:
1.进程监控
主要判断进程是否活着。判断进程是否存活一般有以下两种方式:
(1) 传统的解决方案,通过ps进行判断,如我碰到的某个服务就是通过不断的轮询进行判断。当然会有轮询的时间间隔的问题,太大不准确,太小又比较浪费资源。
[
{
"delaySeconds": 15,
"command": {
"value": "ps -ef | grep php-fpm | grep -v grep"
}
}
]
(2) web应用服务几乎都是使用的linux做为服务器系统,可以使用工具supervise解决。supervise是daemontools的一个工具,可以用来监控管理Unix下的应用程序运行情况,在应用程序出现异常时,supervise可以重新启动指定程序。实际服务系统中,我们的应用程序也可通过Supervisor进行管理。Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动。
sh-4.2# supervisorctl
crond RUNNING pid 118, uptime 0:00:43
nginx RUNNING pid 120, uptime 0:00:43
php-fpm RUNNING pid 119, uptime 0:00:43
2.语义监控
进程活着,并不代表服务正常,这时候就需要进行语义监控,结合当前的业务进行的监控,目的是检测服务是否工作正常。解决进程“假死”的问题,具体操作是模拟用户不断对服务器接口发送请求,判断接口的返回结果,成功/失败/超时。监控的类型主要有两种:
(1)http的请求,我们可以通过监控200/4xx/5xx来进行甄别。
(2)rpc请求,需要用独立的客户端进行实施。当然这种监控也需要解决一些实际的问题:a. 非幂等监控如何操作。b. 监控工具需要自研。c. 接口监控任务繁琐。
3.错误日志监控
通常服务一旦出现问题,线上就会打印大量的错误日志。我们也会通过错误日志的监控进行判断线上服务是否正常,即通过监控错误日志的条数进行判断,如:通常情况,线上错误每分钟10条,突然上升到100条,那么肯定是出现问题了,此时需要进行人工跟进。
举例:某个线上的错误日志通常会写到php_error的文件里,这是可以通过Flume进行采集,通过kafka进行收集,然后通过spark进行日志分析,定时拉取进行比对,如果超出设定阈值则进行报警,干系人进行对应的处理。
4.数据波动监控
做为一名开发者不仅要关心业务的实现,还需要关心应用的请求流量波动情况,遇到流量的突增情况,及时应对。如:明星离婚出轨事件,公共突发事件,春晚等节假日,接口被刷等,都会造成流量的波动,进而影响服务的稳定性。此时,我们就需要进行流量的监控。流量的监控的手段,通常通过access日志的统计进行,可以做个每分钟,每小时,每天,每周,每月的环比。解决方案步骤如下:
(1)即时的流量对比,通过天级环比,周级环比进行处理。
(2)基于实时的日志进行分析,包括,日志采集,缓存,计算存储,接口查询,对比判定,报警等步骤。
5.机器资源监控
以上4种是服务的监控,我们还需要监控机器资源的情况,这属于运维的范畴。目的是及时发现资源的不足,掌握主动性,包括:内存、CPU、磁盘、网络等。
优秀的开源框架介绍
- Zabbix
- Open-Falcon
OpenFalcon是一款企业级、高可用、可扩展的开源监控解决方案,具体内容请自行搜索。
3.Prometheus + Grafana
grafana是一个非常酷的数据可视化平台,常常应用于显示监控数据,底层数据源可以支持influxDb、graphite、elasticSeach。
多维度立体监控
横看成岭侧成峰,每个人看待的问题角度不一样。我们对于系统应该多维度,多视角看待问题。如用户,用户只关心系统好不好用,稳定不稳定。服务拥有者主要关心资源的成本,能不能用最少的成本办最多的事。而调用者也不关心,api使用几台机器,更多的关系api是否正常的提供服务。即有了各种视角看待问题:
1. 用户视角,主要是系统是否可用,是否延迟,内容是否完整等;
2.系统拥有者视角,业务准确性,系统吞吐能力(QPS, rt等),健壮性;
3. 旁观者视角,系统无波动,安全稳定;
多维度立体监控包含的内容
- 通用的监控项:
CPU使用率,硬盘使用率,内存使用率,负载,网卡流量等。
- 业务监控项:
举例场景:如统计返回给客户端数据中[]结构出现的次数,模块调用次数等,某个模块要接入广告,但调用这个模块的入口比较多。此时,可以通过这种多维度立体监控进行统计,特点:
(1)业务隔离,原来的业务逻辑基本不动。
(2)随时修改,即时生效。
(3)运行时不占用资源,几乎0消耗资源。
多维度立体监控的设计
前面介绍了多维度立体监控的一些内容,那么我们怎么去设计,先看方案选择:
1.基于日志的统计,采用统一的日志格式,flume + kafka收集,然后通过开源的工具收集统计。
2.不基于日志,打造多维度立体监控平台,如上面的例子,我们可以采用懒汉模式,先在前端机计算好,然后通过通道上传到计算中心,进行数据处理和落地。此时我们可以提供标准化的环境和产品,规范研发接入,提高架构的高度集成能力,优势在于开销可控。
日志平台vs立体监控平台的对比
我们先来对比下两者的区别:
- 日志平台
(1) 业务层需要执行100次action.log。
(2) 日志代理工具对日志进行切割日志上传。
(3) 然后传给计算平台进行处理count(lines)。
2.立体监控平台
(1) 业务层,立体监控平台采用的懒汉模式,即先在每台前端机上进行数据处理,写时计算。即在内存中执行100次加1,如:monitor.sum(业务id,1)。
(2) 然后上报一条数据id=100。
(3) 平台处理,则可以直接落地。
对比分析,业务应用在本地通过UDP或者http与采集程序相连接,上报数据,因为是本地模式,基本没有网络请求。而agent定时上报聚合后的数据,节省带宽资源。响应的服务器不需要大量的计算,节省CPU,降低复杂度。
当然,也有一些系统采用共享内存的方式,不过考虑开发维护成本,不推荐采用。而且不同的语言实现共享内存比较困难。
多维度立体监控职责边界
接入方:定义监控目标,按照使用规则进行产生监控数据。
平台方:(1)数据汇总;(2)告警条件设置与发出告警;(3)数据存储;(4)图形化展示等其他可扩展的方面。
多维立体监控架构图
业务接入和Agent
- 业务方使用
通过多维度立体监控,我们可以监控函数或模块的一些常规参数:
(1)调用次数;(2)平均耗时;(3)最大耗时;(4)异常次数;
- 调用方式分成两种:
(1)硬编码方式,即在需要调用的地方通过代码写如固定的内容,如:
...
Monitor.sum(函数业务id, 1);
...
(2)注解的方式,这种是java程序的一种方式。感兴趣的话,可以自行查看。
监控组合
多维度立体监控应该提供定制化的服务,即:用户可以根据需求,自由组合监控视角。如:重构后的接口和重构前的对比,模块调用次数,模块的响应时间(模块不仅指的单个api接口,可能是多个接口的公共组合体)。
告警设置
一套好的监控系统应该提供完备的告警功能。告警设置可以设计为单一监控和多维度组合告警。用户可以根据业务,自由选择不同的方式按需设置。我看过很多系统宣称有告警,流量突发了,接口挂了却没有报警,等于没有监控。这相当于超市里货物充足。到是到不了居民手中一样,还是处于被动的局面。
以上,是我根据自己的学习和实践的总结,包括了传统的监控和多维度立体监控的架构设计思考,也许还有更先进的监控系统,所有的监控的系统都是随着业务的发展而发展的,目标是在于帮助服务提供者掌握主动,更快的应对突发情况。限于篇幅,没有更细致的说明多维度立体监控的实现,如有兴趣,欢迎一起交流~