接上篇:
https://developer.aliyun.com/article/1222700?spm=a2c6h.13148508.setting.21.4f394f0em1x0Jq
随着公司业务蓬勃发展,人员激增,微服务暴增,研发人数和告警也剧烈增长。为了提升告警触达率和响应率,我们重新使用了Apollo配置中心的多语言SDK,通过Go自研了一套基于Apollo业务的应用提醒,整体流程如下:
通过Grafana收集到ES告警或其他场景下的告警,再通过 metrics应用关联到alert,告警时会转发到前文提到的Go语言编写的精准告警服务上。精准告警服务解析到对应应用,根据应用从Apollo配置中心中获取到owner姓名、手机号等信息,再基于此信息通过钉钉进行告警,极大提升了消息阅读率。
此外,我们还引入了阿里云的应用实时监控服务ARMS,能够在没有任何代码改造的前提下,支持绝大部分中间件和框架,比如Kafka、MySQL、Dubbo等。云原生化后,仅需要在deployment里添加注解即可支持相关探针的加载,微服务的可维护性极为友好。同时,还提供了较为完整的trace视图,可以查看线上应用节点调用日志的整个trace链路,也提供了甘特图的查看方式和依赖拓扑图、上下游耗时图等数据。
可观测在国内微服务领域已遍地开花,因此,F6公司也升级了可观测思路。业界广泛推行的可观测性包含三大支柱,分别是日志事件、分布式链路追踪以及指标监控。任何时代都需要监控,但是它已经不再是核心需求。上图可以看出,监控仅包含告警和应用概览,而事实上可观测性还需包括排错剖析以及依赖分析。
最早的监控功能使用主体是运维人员,但运维人员大多只能处理系统服务告警。而上升到整个微服务领域,更多问题可能出现在应用之间,需要进行问题排障。比如服务出现了慢请求,有可能是因为代码问题,也可能因为锁或线程池不足,或连接数不够等,以上种种问题最终表现出来的特征是慢和服务无法响应。而如此多的可能性,需要通过可观测性才能定位到真正根因。然而,定位根因并非真实需求,真实需求更多的是利用可观测性分析出问题所处节点,然后通过替换对应组件、进行熔断或限流等措施,尽可能提升整体SLA。
可观测性还可以很好的剖析问题,比如线上服务慢,可以观测其每个节点的耗时、每个请求中的耗时等。依赖分析也可以得到解决,比如服务依赖是否合理、服务依赖调用链路是否正常等。
随着应用越来越多,对于可观测性和稳定性的诉求也越来越多。因此,我们自研了一套简单的根因分析系统,通过文本相似度算法将当前服务日志进行归类聚类分析。
上图为典型ONS故障,依赖服务进行服务升级。如果这是通过日志抓取智能分析出来的日志,做了很长时间SRE后,变更也会对于线上稳定性造成很大破坏。如果能将变更等也收集到可观测体系中,将会带来很大好处。同理,如果能将ONS要升级的信息收集到可观测体系中,通过种种事件关联,能够分析出根因,对于系统稳定性和问题排查将极为有益。
F6公司和ARMS团队也进行了深入合作,探索了可观测的最佳实践。ARMS近期退出了一项新功能,将traceID直接透出到HTTP头,可以在接入层日志中将它输出到对应日志,通过Kibana进行检索。
客户在发生故障时,将日志信息和traceID 一起上报给技术支持人员,最后研发人员可通过traceID快速定位到问题原因、上下游链路,因为traceID在整个调用链路中是唯一的,非常适合作为检索条件。
同时,ARMS支持直接通过MDC透传traceID,支持Java主流日志框架,包括Logback、Log4j、Log4j2等,也可以将traceID作为标准Python输出。
上图展示了典型的日志输出场景下ARMS的后台配置,可以打开关联业务日志和traceID,支持各种各样的组件,只需在日志系统中定义eagleeye_traceid即可输出traceID。
上述方案较为简单,研发的修改也很少,甚至可以做到免修改,且对于Loggin和Trace的关联程度做到了较大提升,减少了数据孤岛。
ARMS为进一步降低MTTR,提供了很多数据,但是数据如何到达SRE、DevOps或研发运维人员手里,依然需要花费一些心思。
因此,ARMS上线了运维告警平台,通过可视化方式完成了告警转发、分流等事件处理,可以通过静默功能、分组等,支持多种集成方式。目前F6在用的包括Prometheus、buffalo、ARMS以及云监控,其中云监控包含了包括ONS、Redis在内的很多数据,研发人员或SRE人员在钉钉群里认领对应的响应事件即可。同时还支持报表、定时提醒、事件升级等功能,便于事后复盘和改善。
上图为线上处理问题的界面截图。比如钉钉群里的告警会提示上一次相似告警由谁处理、告警列表以及对应事件处理流程等。同时,还提供了过滤功能,可以分割内容,通过字段丰富或匹配更新等方式替换内容填充模板,用于精准告警,比如识别到应用名称后,可以关联到对应应用的owner或告警人员。此功能后续也将逐步替代前文用Go语言写的Apollo SDK应用。
同时,我们也借鉴了ARMS免修改注入Agent的方式。ARMS通过one point initContainer的方式注入了很多ARMS信息,也挂载了一个名为home/admin/.opt的mount用于存储日志。正因为有initContainer,它才能够实现自动升级。
在initContainer中,可以通过调用ARMS接口获取到当前ARMS Agent最新版本,然后下载Java Agent最新版本,放到mount目录下,与目录下对应的数组Pod进行通信,通过共享volume的方式完成Java Agent共享。过程中最核心的点在于,通过JAVA_TOOL_OPTIONS实现了Java Agent挂载。
通过上述方式,我们模拟了一套流程,通过openkruise组件workspread使用patch方式修改deployment。最简单的实践是利用openkruise workspread给对应的deployment打注解,从而使得无需由研发或SRE团队进行处理,只要编写对应CRD即可,CRD过程直接注入JAVA_TOOL_OPTIONS(见上图右下角代码)。其应用场景也较为丰富,可以做应用流量回放、自动化测试等。
除了ARMS等商业化产品外,我们也积极开源,拥抱Prometheus社区,接入了较多Exporter组件,包括SSLExport和BlackBoxExporter,极大提升了整个系统的可观测性。Exporter可以用于黑盒探针,比如探测HTTP请求是否正常、HTTPS请求是否正常、DNS是否正常、TCP是否正常等,典型的使用场景是探测当前服务入口地址是否正常。SSL证书异常更为常见,通过SSLExporter可以定期轮询证书是否过期,进一步提升可观测性。
除了日常服务可观测,我们还实践了成本可观测等优化项目。对于云原生环境,可以利用kubecost开源组件进行成本优化,直接输出资源使用率以及报表等,反馈给研发人员进行优化,甚至可以用来发现CPU和内存是否呈正常比例,尽可能实现资源合理分配。
3. 未来畅想
eBPF云原生组件愈发进入到深水区,很多问题不再只停留于应用层面,更多地会出现在系统层面和网络层面,需要更加底层的数据进行追踪和排障。利用eBPF可以更好地回答Google SRE提出的比如延迟、流量、错误率、饱和度等黄金指标出现的问题。
比如Redis进行闪断切换的过程中,可能会形成TCP半开连接,从而对业务产生影响;再比如TCP连接刚建立时,backlog是否合理等,都可以通过数据得到相应结论。
chaos-engineering混沌工程鼓励和利用可观测性,试图帮助用户先发制人地发现和克服系统弱点。2020年6月,CNCF针对可观测性提出了特别兴趣小组。除了三大支柱外,CNCF还提出了混沌工程和持续优化。
对于混沌工程是否能划分在可观测性里,当前社区依然存在疑议,而CNCF的可观测性特别兴趣小组里已包含了chaos-engineering和持续优化。我们认为,CNCF的做法有一定道理,混沌工程可以被认为是一种可观测性的分析工具,但其重要前提是可观测性。试想,如果在实施混沌工程过程中发生故障,我们甚至都无法确定它是否由混沌工程引起,这也将带来极大麻烦。
因此,可以利用可观测性尽可能缩小爆炸半径、定位问题,通过chaos-engineering持续优化系统,提前发现系统薄弱点,更好地为系统稳定性保驾护航。
OpenTelemetry是一个通过多个项目合并而来的开源框架。我们需要更加面向终端研发统一的可观测性视图,比如期望将logging、metrics和tracing数据进行互相关联打标,尽可能减少数据孤岛,通过多数据源的关联提升整体可观测性。并利用可观测性尽可能缩短线上故障排查时间,为业务服务恢复争取时间。