e-works数字化企业网  »  文章频道  »  基础信息化  »  网络与安全

如何自己动手写一个监控系统?

2017/3/6    来源:开源中国社区    作者:佚名      
关键字:监控系统  API设计  
其实在做这个监控系统之前我从来没有做过监控,到处问人有没有经验可以借鉴,问了一圈发生公司没有任何一个人可以帮到我,于是定下心来自己完全琢磨每个细节该怎么设计,后来发现一些想法在别的开源软件中也是存在的,所以说这个系统没有参考任何一款软件,最后开发出来并且非常平稳的运行了1年半时间。
    1)报警配置信息的录入 
 
    这部分比较简单,就是一个简单的管理系统,架构如下所示:
 
如何自己动手写一个监控系统?
 
    配置信息具体要存什么,看你自己需要,每个人有自己的想法我之前的思路是:
 
    (0)定义本配置所属的服务,比如web服务,rpc服务,cache缓存服务,mq服务,sql服务。
 
    (1)定义一个采样次数的总数,比如10次采样样本为一次计算单位。
 
    (2)定义一个采样样本不过关的次数,比如4次,也就是10次里面有4次样本不过关就报警。
 
    (2.1)单个样本里的成功率必须>=某个阀值
 
    (2.2)单个样本里的平均耗时必须<=某个阀值
 
    (2.3)单个样本里的最大耗时必须<=某个阀值(可选)
 
    (2.4)单个样本里的最小耗时必须<=某个阀值(可选)
 
    (2.5)单个样本里的TP99数值必须<=某个阀值(可选)
 
    (2.6)其它,你想怎么做就怎么做,规则你自己定,你就是规则之王。
 
    (3)报警周期,就是后面如果报警,多少时间之内同种类型的不再报警,如果你不需要就设置为0,那么有多少报警都会发出去,造成报警短信洪灾。
 
    单个样本到底是啥意思? 客户端调用埋点jar包里的API,会调用很多次,然后如果你定义了6秒钟收割一次进行数据采样汇总,上传到服务器,那就是一个采样样本。
 
    PS:如果在这6秒钟某个API被调用1万次,成功6000次,那么只会上报一条数据给远程服务器,类似于{key,10000,6000,...其它信息},要弄清楚这个概念,绝对不会上报1万条数据给远程服务器。
 
    好,到此,针对每种服务的报警标准都已经存在mysql数据库了。有的时候,用户(单位内部各个业务系统)会说,我需要每种服务的参数都要定制,那么你需要自己扩充这些达到定制的需求,还有说我针对时间段的需求要定制,我针对每个URL的参数要定制,这个你自己举一反三就可以了。
 
    2)业务统计信息上报 
 
   如何自己动手写一个监控系统?
 
    这部分代码在client_metrics里已经实现了,花时间看一下就知道设计思路。
 
    上报的时候要包含以下一些信息:
 
    {产品,所属服务,机器ID,key,total调用次数,成功次数,平均耗时,最大耗时,最小耗时,TP99...等其它你想要的信息},这里解释一下前4个字段的意思。
 
    举个例子:
 
    产品:公司金融产品
 
    服务:因为这个产品会包含一些http服务啊,rpc服务啊,缓存服务啊,sql服务啊,所以你要标记出来。
 
    机器ID:就算你指定了rpc服务,你不会只部署一台吧,你肯定有多台,那你得指定是哪一台啊,不然不知道发生在哪台机器上啊,这个你可以写一个静态函数获取,比如我们采用了发送时获取{ip:本进程监听端口}这样,以后就不再重新获取,复用这个值。
 
    key:针对http服务,就是你的url;针对redis服务,就是你的命令;以http服务为例,你的url如果有变化的参数,你要写成模板类型的值,不然key的个数发生爆炸,比如http://ip:port/a/1/b 这样的,里面的1会发生变化,你不能直接把这个作为key,你得写成http://ip:port/a/xxx/b,大概就这个意思。
 
    有的人说埋点你不能影响我的业务速度,不能影响我的内存,这个在设计时候都要考虑。
 
    还有如果监控的数据接收服务器全部宕机了,也不能影响业务,这个请自己看client_metrics,看完了就知道大体思路了,如果你觉得可以优化得更好你自己优化吧。核心思想是异步上传,容许一段时间的数据不是100%准确(发生在所有远程数据接收服务器全部宕机的前提下)。
 
    另外我们当时做数据汇总时,以web为例,web可能会有几十个URL的数据,我们上传时就已经做了所有数据的一个综合统计,比如所有url的调用次数,平均耗时,这样后面如果你要看这些数据,直接用这些数据作为计算基础就可以了。
 
    然后我们还做了一个掉0检测,就是如果某个新的key第一次出现时,我们在内存中记住了它,如果它在某个采样周期内没有出现,我们就会上报这个key的数据为0,有些场合可以用来做掉零检测。
 
    另外如果你不是java语言的程序,怎么埋点?一个可行的是你用Netty写一个UDP服务器,内部嵌套上面的java jar包,本质上是做了一个代理然后所有程序发送UDP数据给你,这里可以优化,思路你自己想,(maybe QUIC协议你可以调研一下)。
 
    好,数据到了Netty服务器之后,这里是HTTP协议上报的哈,为什么要一份为2,一式2份呢?目的是为了数据上传入HBase和数据入MQ互相不干扰,也就是说,hbase全部宕机不影响数据进MQ,MQ全部宕机不影响数据入hbase。
 
    hbase:用来存储海量历史数据,这样如果你收到了报警信息,你可以查啊,调出那个时候的数据看是不是真的有问题,用于历史回溯。
 
    mq:用于存数据,作为实时计算的数据源啊,不然谁来发送报警短信和邮件呢?
 
    然后hbase那里有一个redis.这个是干嘛的?因为每个数据里面的产品我可以实现定义在配置库里,但是服务,机器ID,key这些是完全动态的啊
 
    所以每一条数据来了后,要需要先查redis是否存在,不存在的话,要相应的维护到hbase里的表里,这样慢慢构建好这个产品的这些信息,回头在界面上才可以调出来。所以redis就是起加速作用,不然每一条信息来了,你也不知道服务和机器id,key是不是已经存在了的,然后插入到hbase,很慢啊,量大了你肯定扛不住。
 
    3)报警信息实时计算 
 
 如何自己动手写一个监控系统?
 

责任编辑:李欢
本文来源于互联网,e-works本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供,并以尽力标明作者与出处,如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。联系方式:editor@e-works.net.cn tel:027-87592219/20/21。
e-works
官方微信
掌上
信息化
编辑推荐
新闻推荐
博客推荐
视频推荐