接上篇:
https://developer.aliyun.com/article/1222679?spm=a2c6h.13148508.setting.28.4f394f0em1x0Jq
2. 函数计算内置可观测能力
上图展示了函数计算所有的可观测能力,由四大部分组成,分别是指标、日志、调用链、APM。
• 指标:与云监控集成,在函数计算的监控中心上提供云监控的指标。为了兼容SLS用户与Grafana用户的体验,也提供了SLS Dashboard与Grafana Dashboard的解决方案;
• 日志:与日志服务无缝集成,提供了函数日志、请求日志、实例日志等;
• 调用链:与阿里云的链路追踪产品进行了无缝集成,函数计算会默认上报系统内部关键链路的时间。并且将调用链的上下文信息传给用户的runtime,用户可以在函数里基于Jaeger或OpenTelemetry进行自定义埋点;
• APM:与阿里云的AMS产品集成,用户可查看runtime指标,比如JVM的GC数据、MySQL的连接情况等。考虑客户更喜欢使用三方SaaS的可观测产品,我们也对此提供了集成方案。
函数计算主要通过数据采集、数据存储、数据处理和数据展示为用户呈现可观测能力。用户的业务代码在函数计算的执行引擎中运行,执行引擎会根据用户设置的函数内存创建不同规格的函数实例,用户函数最终在不同的函数实例中执行。执行引擎为异构的,底层支持ECS与神龙裸金属执行环境,对应的函数实例分别是Docker Container与安全容器。
执行引擎的内部实现了agent,负责函数实例生命周期的管理、函数实例健康状态的监测、观测数据的收集处理与上报。
数据处理侧具有三个特点:
• 无侵入:观测数据采集不占用函数实例的CPU内存资源,因为agent是部署在函数实例之外,占用的是函数计算系统的资源。用户无需关心如何处理的,也不占用用户资源,用户无感知,对函数实例也没有侵入;
• 支持异构的执行环境:在不同类型的执行引擎中,日志指标调用链的处理会有一定区别,我们也对这些区别进行了适配,分别适配了ECS执行环境与裸金属环境;
• 支持多租:ECS环境不存在多租的问题,但神龙裸金属的执行环境里,用户是安全容器级别的隔离,执行环境里会有不同用户的函数实例,同一个agent需要支持不同用户实例的日志、指标与调用链的收集。
我们最终的目标是为了提供开箱即用的可观测平台,数据存储到用户对应的云产品后,需要提供处理数据平台。我们基于Serverless架构实现了数据处理平台,前端需要查看数据时,由 Serverless架构的Web API从用户云产品里获取原始数据,并进行聚合、格式转化后传递给控制台。控制台上有三个函数,分别对指标、日志与调用链进行处理。
经过层层处理后,最终实现了开箱即用的完整统一的可观测平台。平台上罗列了非常丰富的、多层次、多维度的指标上,有集群/服务/函数指标、请求实例级别的指标、计量指标、函数级别的日志、实例级别日志、请求日志、实时日志等,可以实时查看tail日志,也可以根据grab对日志进行搜索。
此外,函数计算会自动上报系统内部的调用链,比如冷启动时间、调度时间,可以串联上游函数计算,识别开源调用链的header,如果用户将上游的header传进函数计算即可基于用户的调用链来创建子调用链;也可以串联下游函数字段,将调用链的上下文传给用户的runtime并创建自定义的调用链,比如创建访问数据库的调用链或写本地数据的调用链等。
每个执行引擎里有agent负责实例生命周期的管理、观测数据的采集与上报。每个agent里都有一个container manager负责管理函数实例生命周期。创建新的函数实例时,container manager会记录一份函数实例的元数据,并分别启动指标采集、日志采集与调链采集的协程。每个函数实例都有自己的协程,各个函数实例的采集互不影响。实例销毁时,观测协程也会随之关闭。
以上设计使得数据采集具有如下几个特点:
• 采集函数调用产生的Metrics、Logs、Traces;
• 不侵入用户runtime,不占用用户资源;
• 支持多租,能够并发收集不同用户的数据;
• 支持不同执行环境;
• 数据采集随实例生命周期启停。
指标采集主要是请求级别的指标与实例级别的指标。其中请求级别指标包括请求执行时间、错误类型、调用类型、资源类型等;实例级别指标包括实例CPU、内存、网络流量等。
日志采集上,收集函数输出到标准输出的日志,包括函数日志和实例日志。调用链基于 OpenTracing 的协议自动上报系统关键链路的耗时、冷启动耗时、异步调用的队列积压耗时等。
用户登录控制台查看数据,前端收到了用户查看数据的请求后,需要由Web API为前端返回数据。Web API负责从用户的云产品里获取原始数据,再到业务逻辑里处理这些数据,然后将它以与前端约定的格式返回给前端。我们将Web API的处理逻辑移至函数计算上,充分享受了Serverless架构的红利。
此外,架构可实现毫秒级扩容,可以轻松应对突发流量。业务开发者只需关注业务逻辑的实现,无需关注底层用了多少台计算资源,也无需维护服务器,开发运维效率更高了。
为了保障服务的可用性与可靠性,我们在国内外多个区域进行了部署,尽可能避免跨洋网络访问慢的问题。
最终,我们为用户提供了开箱即用的统一可观测平台,提供了非常丰富的函数级别、服务级别、集群级别、请求级别以及实例级别的指标。指标的聚合粒度有秒级、分钟级、小时级。平台尽可能地将函数计算内部的指标暴露给客户,让客户更信任底层的执行环境。还提供了请求粒度的监控、请求的调用结果、请求的执行时间、内存使用量、日志、调用链等。
在请求调用链里,可以看到函数计算系统上报的调用链、调度的时间、进行调度计算资源的时间、系统冷启动的时间、下载代码/下载自定义镜像的时间、启动执行环境的时间以及真正执行用户代码invocation的时间等,以上指标都由系统自动上报,用户无需进行任何操作,开箱即用。
其次,平台兼容了传统开发者的开发习惯,提供了实例级别的监控、实例级别的指标,可以查看CPU内存、网络流量、请求数等;也可以查看函数维度的聚合,比如函数的CPU情况、实例数量、每个实例的指标,提供了实例级别的日志,还可以登录到实例里,让用户对自己的执行环境更有信心。
最后,数据开放,协议开源部分。FC将所有观测产品都存入用户的云产品里,实现了数据开放;链路追踪遵循开源的OpenTracing协议,可以串联上游,识别上游开源的协议头,也可以连接下游,将trace的上下文传入用户runtime。用户可以基于当前调用链根据Jeager或OpenTelemetry进行自定义埋点。
上图右下角为MNS Trigger的示例。上游用户记录了Publish Message与在MNS队列里等待的时间。到了函数计算后,函数计算自动记录了调度时间、在函数计算的异步消息队列里堆积的时间以及冷启动的时间。然后将调用链传给下游,用户埋点了自定义的调用链,即可看到完整的端到端的调用链。此时如果有一个请求端到端的时间很长,通过调用链即可明确时间花在哪里,能够进行更有针对性的排查与定位。
下文将通过两个demo来展示可观测能力。
Demo1:函数错误问题定位
从监控大盘可见函数有41个错误,点击“41”可查看错误列表页面,如下图。
先查看服务级别的错误,再查看函数级别的错误数,最后即可定位到出错的请求。
点击详细错误可以查看其请求日志刷新。处理过程从指标下钻到请求,再到日志,最终实现快速问题定位。
Demo2:冷启动耗时分析
从监控大盘发现某请求执行时间特别长,但业务逻辑并不复杂,预计为百毫秒级别,而端到端的请求却执行了7秒。
点击查看其调用链,发现函数执行时间只有170毫秒,但遇到了冷启动。其中下载代码花费将近3秒,函数实例启动花费4秒多,最终总共花费7秒。
可以先看能否缩小代码包,减少下载代码的时间。另外,优化启动时的逻辑,减少函数启动的时间。如果对冷启动时间特别敏感,也可以使用预留实例来完全规避冷启动。平台还给出了冷启动优化的最佳实践,用户可以基于最佳实践进行自定义配置。
1. 函数计算对开源和可观测能力的探索
大多数可观测服务提供商的SDK都是后台定时采集数据,批量发送。而FC实例在请求执行完成后会立即冻结实例,下次请求来时才解冻。如果发送时间刚好处于实例冻结时期,则会导致数据发送失败。
FC Service代表函数计算系统,这里主要是函数的执行引擎。Function Runtime是函数实例中的runtime。实例启动之后会先调用Initialize接口,用户可以在其中做自定义初始化操作,比如建立数据库、初始化全局配置、启动ARMS的采集,初始化结束后执行Invoke逻辑,Invoke 结束后系统会立即冻结函数实例。如果此时后台的Flash interval发送观测数据,则必定发送失败;如果后台的观测数据发送时间刚好落在实例的活跃时间内,则可发送成功。
不做任何处理的情况下,运气好可发送成功,运气不好则发送失败。函数实例的生命周期由函数计算系统控制,用户不可见,因此用户无法预知这些观测数据发送是否能成功,这会导致数据的缺失与可观测功能不稳定。
为了解决上述问题,函数计算扩展了编程模型,允许用户监听实例的生命周期,用户可以自己实现冻结和解冻的函数逻辑。在Freeze前会告诉用户将执行Prefreeze代码,可以在Prefreeze里Flush观测数据;在回收销毁函数实例前,会执行用户的Prestop函数,用户可以在Prestop里关闭连接,停止数据采集。基于以上技术,可观测数据即可稳定发送。
也是基于以上技术,我们内部得以与ARMS APM进行集成,也提供了集成三方SaaS厂商如NewRelic的解决方案。
上图列出了FC目前已经应集成或已经提供解决方案的产品与技术,我们也将在此方向进行持续探索。
今天的分享就到这里,谢谢大家。