作者:丛霄(阿里云函数核算研制工程师)

布景介绍

全保管的 Serverless 核算渠道能给用户带来更少的运维价值、更强的稳定性和更快的弹功能力,在 Serverless 落地的过程中,遇到的一个很大的挑战是 Serverless 渠道怎么给予开发者满足的安全感。让开发者们无担负地运用并信赖 Serverless,是咱们一向寻求的目标。

全保管的初衷是为了减小开发者的运用和运维杂乱度,但这一定程度上削减了用户对本身服务的操控权力。比如在很多场景中,用户会想知道,怎么能够掌握自己运用的实践运转情况?运用出现问题时怎么能快速确认是本身问题还是云渠道问题?假如是云渠道的问题,怎么能快速恢复服务,及时止损?

这些问题的根本原因,都是用户对云渠道无法做到完全的信赖,这也进一步阻碍了他们搬迁运用和扩展事务场景。所以咱们也在思考,怎么打破这种不信赖局势,让用户拥有更多资源层面上的掌控力,但又能远离资源层的杂乱运维。

在这样的布景和需求下,阿里云函数核算立异推出了 Serverless 场景下的函数实例指令行操作功用,支撑用户在操控台界面登录进函数实例内部,或者运用东西对实例履行指定的指令。 本文将详细介绍这个功用的运用方法和运用场景。

完成 Exec 功用定位及运用方法

实例指令行操作功用供给和 K8s Pod Exec 与 Docker Container Exec 一致的运用体会,支撑在函数实例的实在运转环境中履行详细指令。

一起,由于 Serverless 极致弹性、按量收费等特性,在 Serverless 场景下的实例 Exec 功用又与 K8s 和 Docker 有着一些本质的差异:

  1. 只能对还存活着的实例(包括预留常驻实例和按量活泼实例) 履行 Exec 操作,假如按量实例空闲超时被释放,则无法再履行;

  2. InstanceExec 恳求不占用实例的并发度。因此即便函数的实例并发度设置为 1,也能够一起履行 InvokeFunction 和 InstanceExec 操作;

  3. InstanceExec 的一次操作被视作一次 InvokeFunction 恳求调用。只需 InstanceExec 恳求树立的 websocket 衔接没有和函数实例断开,那么函数实例将一向处于活泼状况,和 InvokeFunction 采用同样的计费规则。用户能够设置 InstantceExec 的 idleTimeout 参数让客户端在空闲指定时刻后主动断开衔接。

实例指令行操作功用支撑在操控台上登录实例、运用 Serverless Devs 东西履行指令,或者 SDK 调用接口,履行指令。

操控台登录实例

在函数核算官网操控台上在函数详情-监控目标-实例目标页面,在最右侧能够对实例履行登陆操作。

点击“登录实例”,界面将会调到一个终端界面,即可马上登录进实例,履行指令进行问题排查。

在函数详情-监控目标-实例目标页面,点击实例 ID 能够进入到函数的实例详情页面,界面右上方有登录实例的按钮,点击即可进入实例。

SDK 调用

以 golang SDK 为例,其它 SDK 的调用方法大都相似。

SDK 对 InstanceExec API 进行了封装,在调用接口的时分需求运用建 OnStdout、OnStderr 传入两个回调函数,回调函数界说了处理 Exec 通道回来数据的详细逻辑 ;一起能够运用回来的 execConn 输入 stdin 音讯以传输给远端的 Exec 通道。

command := []string{"/bin/bash"}
execConn, err := client.InstanceExec(
      fc.NewInstanceExecInput(
        serviceName, functionName, instanceID, command,
      ).WithStdin(true)
             .WithStdout(true)
             .WithStderr(true)
             .WithTTY(true)
             .WithIdleTimeout(120)
             .OnStdout(
        func(data []byte) { fmt.Printf("STDOUT: %s\n", data) },
      ).OnStderr(
        func(data []byte) { fmt.Printf("STDERR: %s\n", data) },
      ))
if err != nil {
  fmt.Printf("%v", err)
}
if err := execConn.WriteStdin([]byte("ls\r")); err != nil {
  fmt.Println("Write Stdin error", err)
}

适用场景

排查线上问题

在一些日常的场景下,实例指令行操作会带来更契合用户习气、更高效快捷的排查问题方法。

用户小王是 Serverless 小白用户,写完一个程序部署到函数核算后,发现函数中设置的环境变量不收效,假如进一步排查,则需求修正代码,打印日志,重新部署,查看日志,运用这样繁琐的排查方法。现在凭借实例指令行操作,小王能够直接指令:s exec {instance_id} ENV,便能一步定位问题。

实例指令行操作供给了快捷的登录体会,能帮助用户处理杂乱场景下的运用问题。 一些情况下,用户已经无法经过函数日志、监控目标来详细定位问题,需求凭借比如 coredump 、tcpdump、jmap 等东西进行深化排查。

比如,用户小李发现自己的线上程序最近会出现一些函数错误,报错内容都是衔接长途某服务超时。小李怀疑是函数实例与远端服务的网络链接不稳定,想进入实例内部,查询剖析下实例与远端服务的网络情况。他能够按照这样的过程进行:

  • 登录进实例内部后,先装置 tcpdump 东西,需求履行 apt-get update 和  apt-get install tcpdump 两条指令:

  • 装置结束后,履行 tcpdump 指令,对远端服务 IP 的恳求进行抓包,并将抓包结果保存在 tcpdump.cap 文件中:

  • 抓包结束,凭借 OSS 指令行东西 ossutil64 ,将 tcpdump.cap 文件上传到自己的 OSS ,然后下载到本地凭借剖析东西 wireshark 能够进行剖析。

程序功能优化

很多时分,开发者需求经过各种 profiling 东西来剖析功能、资源运用等问题。比如运用实例 CPU、内存等资源运用不契合预期;运用功能低于预期,经过 profiling 东西找到瓶颈等等。经过实例指令行操作,开发者能够方便的运转语言、框架供给的各种 profiling 东西,优化程序功能和资源运用。

以运转在函数核算上的高德自主出行为例,其峰值 TPS 会到达数十万等级,作为实时在线运用,服务能接受的恳求推迟在几十毫秒等级。考虑到本钱压力,在上线前他们期望压测出单实例最高能接受的 TPS 和对应的调用推迟,以此评估需求的实例数量。

可是高德在压测中发现单实例的平均/长尾延时不契合预期,当单实例 TPS 到达 300 TPS 的时分,恳求推迟会直线上升。他们想确定,是否是自己的运用程序哪里存在功能瓶颈,或者是函数核算运转时的功能存在问题?凭借实例指令行操作,他们能够登录进实例内部,经过 profiling 深化剖析后发现了功能问题,最后优化了程序功能到达了上线标准。

下面以 custom runtime 为例:demo 示例程序运用 golang 编写并部署到函数核算上:

  • 登录进入实例后,下载 golang 装置包 :

  • 并解压装置 go :

  • 履行 go tool pprof 指令,并产生剖析文件:/root/pprof/pprof.bootstrap.samples.cpu.001.pb.gz,

  • 最后凭借 OSS 指令行东西 ossutil64, 运转 ./ossutil64 cp 指令,将剖析文件上传到自己的 OSS Bukcet 中 ,便能够下载到用户本地进行可视化剖析。

总结

实例指令行功用的推出希望能消除用户运用 Serverless 的“最后一公里”,直接将实在的函数运转环境展现给用户,尔后 Serverless 将不再是一个“黑盒”,用户能够愈加信赖和依赖 Serverless 渠道来扩展更多的事务场景和规模。

作者简介: 丛霄,阿里云函数核算研制工程师,专心于云原生 Serverless、分布式系统稳定性等范畴。

戳​​此处​​,查看函数核算更多详情!