在任何生产级别的代码里,我们都能看到监控代码。监控代码为我们提供
- 硬件性能(CPU,磁盘,内存,网络)
- 功能完整性
- 服务质量(客户等待时间,失败比例)
- 采集的业务数据
…
监控的实现方式也有很多,基于日志文件的,基于事件队列的,基于网络请求(比如当当的cat),基于时序数据库的。。。。
监控系统的实现,和所有其他代码一样,我们希望他
- 高性能:降低对业务代码的影响,支持大量的数据采集,紧急监控事件及时/实时响应
- 低耦合:从耦合方式上而言一般而言代码耦合 < 静态库耦合 < 动态库耦合 < 进程间通讯耦合(如HTTP,消息中间件等等)。最底线的目标是尽量减少代码级别的侵入。从耦合逻辑上言尽量希望减少被监控进程中为监控服务的代码的量。
- 功能完善:报警通知,数据持久化,数据离线/实时分析,智慧化运维。
监控大概有两种方式,一种是暴露等待被动采集,一种是主动上报。(其实就是所谓的推还是拉)。两种方式各有优劣。被动采集不适用于业务数据的监控(如上传每一笔业务数据的详细信息),但是耦合度更低(把采集逻辑内聚到了监控进程中),另外稳定性也更好(即使外部系统全部崩溃通过暴露也能知道代码的当前状态)。而主动上报在及时性上的优势明显。目前的主要实现是业务信息采集走主动上报,实时指标走暴露等待被动采集
程序员最喜欢的方式,莫过于写完程序,然后标记自己需要监控的字段(如配置文件或者java的注解)。而且不预期这个标记操作会对自己的代码的正常编译打包和线上操作没有任何影响。而一些具体业务的信息上报,应该属于相对独立的业务信息采集系统。
这里面就涉及了一个核心的价值观问题—————开发程序员应该知道监控这回事,但是架构师要为他们实现一个他们不需要知道如何实现的系统。是否要监控,监控代码的哪个值,这些必须是程序员想好的事情。架构师不应该超越自己的工作范畴。
常见的一种监控系统是代码侵入的,要求程序员在开发程序的时候就要完成监控指标的采集和上报,最简单的方式就是提供一个lib库。程序员用起来很简单也很开心。但是这并不是意味着这个库不会哪天困扰程序员。打个比方,一个监控的lib库常见的也就是做到异步的汇总的上报机制(输出到文件,队列等等)来节省外部IO请求的次数,但是,这里面一定会为开发者的程序增加线程,而程序员可能并没有留意这个问题。
一些聪明人想到了用打印日志收集文件的方式来做监控。但是,这里的耦合就从代码侵入变成了必须规范日志格式了。我们都不希望有耦合,但是当耦合无法避免,文档的约定的耦合似乎比代码侵入还要更恶心。另外一些程序员想到了将监控代码作为独立的软件,向业务软件加入探针的方式来进行监控。但是同样也要事先约定探针的位置。比如说利用java agent提取jvm某个类的静态字段。显然,这个监控系统的实现必须要依赖对于被监控软件的代码知识。
就非业务数据的瞬时指标监控而言,常见的有以下五种数据类型
- Gauges 瞬时值
- Counter 可以增加,也可以减少
- Histograms 是用来度量流数据中Value的分布情况,Histrogram可以计算最大/小值、平均值,方差,分位数(如中位数,或者95th分位数),如75%,90%,98%,99%的数据在哪个范围内。
- Meters 一个只能增加的计数器,但是可以记录速度
- Timers Timer是Histogram跟Meter的一个组合,比如要统计当前请求的速率和处理时间。
- Summary 不同在于Histogram可以通过histogram_quantile函数在服务器端计算分位数。 而Sumamry的分位数则是直接在客户端进行定义。因此对于分位数的计算。 Summary在通过PromQL进行查询时有更好的性能表现,而Histogram则会消耗更多的资源。相对的对于客户端而言Histogram消耗的资源更少。
基于日志的数据监控
实际上是使用最广泛的那一种。
https://help.aliyun.com/document_detail/89928.html?spm=a2c4g.11186623.6.593.266ac9b59G8bOf
主要就是利用轮训或者事件【基于linux提供的inotify来进行文件和目录变更】。

相对于小企业,大企业有统一的框架。相当于一个容器,提供一个统一的中间件接入能力。这样,他们可以统一打印日志。让开发者只需要关注业务相关的日志。这也是为什么日志方案更加受大企业开心的原因。
252

被折叠的 条评论
为什么被折叠?



