背景
在微服务架构流行的背景下,大部分的App,网站等的后台大都是集群部署架构,很少有单机部署,在集群部署的情况下一个服务请求链路,往往会经过一个或多个负载均衡然后到真正的服务器节点;后台服务集群化使服务拥有了高可用的能力,一台服务器挂掉,流量会自动转发到其他健康的服务器;但是作为后台开发运维人员,还需要关注是哪些节点的服务挂掉了。本文介绍一种通过日志分析来发现节点服务不可用并进行告警的方法。
负载均衡
服务集群
三
问题分析
某个节点服务不可用,可能的原因会有很多,从外向内分析,这里列举几个可能的原因:
- 网络原因:负载均衡与后台服务器之间的网络不同,导致服务节点无法提供服务;
- 服务物理节点断电或者down机:导致机器上的服务全部不可用;
- 服务本身Bug:机器上其他服务可用,但是当前服务本身出现问题死锁,IO Hang等导致服务不可用
以上的原因都会导致服务无法正常提供服务给客户端,因为没有请求触发,很大程度上后台服务会出现日志不打印的情况,即故障的情况下服务出现无日志的情况;虽然没有日志不一定代表服务异常,但是对于一个不间断在线的服务来说,没有日志在一定程度上可以说明服务的运行状态。
负载均衡
服务集群
爱三三
解决思路
基于上述问题的分析,我们可以通过日志是否打印来判断服务是否有异常,可以对服务可用性的监控作为有效的补充。在服务不进行扩缩容的情况下,我们可以定期的去查看当前5分钟打印日志的所有服务器列表,然后再去查10分钟前-5分钟前的打印日志的服务器列表,然后将两个服务器列表进行对比可以比较出来那些服务器没有在打日志。然后将这些异常的服务器列表发送给开发或者运维人员。
该思路步骤可以总结下:
- 日志收集平台收集日志,并记录机器IP
- 写程序查询不同时段的服务器列表并对比
- 对比异常后,发送告警给开发运维人员
方案
通过以上的思路,我们需要自建或者使用现有的日志收集平台,然后写程序来查询服务器列表,最后还需要编写一套告警通知方案,发送给相关的人员。可以看出如果使用自建的方案,还是有一些开发和运维工作。那么有没有一套免开发,免运维的方案可以直接使用呢?答案是肯定的。
在云原生时代,很多业务都是部署在云上,这里推荐一种云上产品:阿里云SLS。无需开发,只需要简单配置,即可轻松解决上述问题。
日志服务SLS是云原生观测与分析平台,为Log、Metric、Trace等数据提供大规模、低成本、实时的平台化服务。日志服务一站式提供数据采集、加工、查询与分析、可视化、告警、消费与投递等功能,全面提升您在研发、运维、运营、安全等场景的数字化能力。
这里我们会使用到SLS的采集,查询与分析,告警等功能来完成对上述服务不可用的监控。这里假设可以已经开通了SLS日志服务。需要的步骤如下:
- 配置业务日志采集,包括创建Project,Logstore,采集配置
- 查询异常服务所在机器IP列表
- 配置告警,并发送通知
使用SLS日志服务方案步骤
日志采集
假设我们是一个Go/Java/Python的应用,进程直接部署在物理机或者虚拟机中,或者部署在K8S集群中,日志是通过文件打印,我们需要先在SLS创建Project和Logstore,SLS的Project和Logstore可以类比为数据库和表的关系。由于接入过程比较简单,并且需要根据业务不同接入方式不同,这里给一篇日志服务的快速入门,里面有很简单的视频演示如何采集服务器上的日志。
查询异常服务IP列表
根据上述的思路,我们需要查询到打印日志所在的服务器IP或者K8S的容器IP,在SLS中有内置字段__source__表示日志的来源,并且默认开启了统计,可以在SQL语句中使用。
查询/分析
15分钟(相对)
40k
38分45秒
32分45秒
36分45秒
28分45秒
34分45秒
30分45秒
40分45秒
26分54秒
日志总条数:964,995查询状态:结果精确
统计图表
原始日志
日志聚类
这里以一个日志库为例,可以看到在15分钟内90多万条日志。我们需要一种方法来获取打印日志的IP,在SLS中可以用__source__内置字段来查询日志所在机器IP。
这里我们需要先查询最近15分钟的IP列表,然后在查询最近30-15分钟的IP列表,然后进行两个列表的对比。我们使用一条SQL来完成这样的功能,SQL如下:
*|SELECTDISTINCT __source__ AS host FROM log WHERE __time__ >= to_unixtime(date_add('minute',-30, now()))AND __time__ < to_unixtime(date_add('minute',-15, now()))AND __source__ NOTIN(SELECTDISTINCT __source__ FROM log WHERE __time__ >= to_unixtime(date_add('minute',-15, now())))LIMIT1000
这条SQL看起来很长,其实原理不是很复杂,逻辑是将最近30-15分钟的IP列表减去最近15分钟的IP列表。拆解来看下子查询:
SELECTDISTINCT __source__ FROM log WHERE __time__ >= to_unixtime(date_add('minute',-15, now()))
子查询用来查询最近15分钟的日志所在IP列表。外层查询使用__source__ NOT IN 来过滤最近15分钟日志所在IP列表;如果最近15分钟前的比最近15分钟的IP列表长,说明有些IP没有打印日志。意味着这些IP的服务可能有异常。
配置告警
在上述查询后,可以点击右上角的另存为告警,选择新版告警。
NEW
数据加工口
协查询分析属性
另存为告警
另存为快速查询
新版告警
查询/分析
SOL
旧版告警
05分36秒
04分45秒
02分45秒
03分45秒
配置告警如下,填写内容模板
标注描述:共发现异常机器数:${__0_count__}个,其中一个为:${host}
告警策略:选择极简模式,行动组选择钉钉-自定义,请求地址填写钉钉机器人的地址。
注意:钉钉机器人需要配置关键词“告警”。
告警监控规则
规则名称:
14/64
机鑫异常检测(无新日志产生)
检宜频率:
固定间隔
分钟
查询统计:
添加
不分组
分组评估:
15分钟(相对)
中添加
严重度:
时
触发条件:
当
有鼓摄
添加标签:?添加
s(alertname告密触发
标楚(title)
添加标注:
现机器机器数:o.count)个,其中一个为:h
添加
描述(desc)
自动添加标注:
恢复通知:
高级配置>
高级模式
普通横式
极葡模式00
告筝策略:
行动组
钉钉-自定义
钉钉-自定义
渠道
请求地址
https://oapi.dingtalk.com/robi
提醋方式
不提醒
c新增查看
内容惯板
SLs内置内容模板
发送时段
任意
自动分派?
+添加通知渠道
更复等待:
分钟
?
取消
确定
接收告警
下图为告警接收结果,其中告警内容显示了告警触发的机器数量,和其中的一个机器的IP,这里告警内容显示为SLS内置内容模板内容,如需定制,可以对内容模板进行修改,或者使用新的内容模板。
告警测试
机器人
潘伟龙
19:30
SLS告警
阿里云账号:1654
钉钉
告警规则名称:机器异常检测(无新日志产生)
告警严重度:中级
告警标题:机器异常检测(无新日志产生)告警触
发
潘伟
告警内容:共发现异常机器数:17个,其中一个
为:11*14
告警首次触发时间:2021-08-0619:27:24
此次评估的触发时间:2021-08-0619:30:08
钉钉
触发告警的实例ID:77f129cbd38a9945-
5c8e25b9202fc-4189c3b
告警规则所在Project:
demo-alert-cigdu
告警状态:触发
潘伟
[详情][设置]
总结
本文主要介绍了一种通过日志分析的方法,来监控节点服务是否可用,并配置告警及通知。可以作为服务监控很有效的一个补充手段。也是使用SLS告警的一个典型应用。
该方法对于具有一定访问量的服务比较有效,每台机器均衡连续的接收流量(本质是打印日志),当服务没有日志时,一定程度上表示服务出现异常。对于可以连续打印日志的服务都可以进行监控。
SLS告警是一站式的告警监控、降噪、事务管理、通知分派的智能运维平台。具有很广泛的应用,想要更多了解可以参考SLS告警学习路径。
参考
进一步参考
- SLS(日志服务)云原生观测分析平台:https://www.aliyun.com/product/sls
- SLS新版告警文档首页:https://help.aliyun.com/document_detail/207609.html
- 欢迎扫群加入阿里云-日志服务(SLS)技术交流(集团同学请直接搜索群号11702236加入), 获得第一手资料与支持
- 后续系列直播与培训视频会同步到B站,敬请留意