Serverless 架构下如何对应用进行调试
在应用开发过程中,或者应用开发完成,当所执行结果不符合预期时,通常要进行一定的调试工作。但是在 Serverless 加架构下,调试往往会受到极大的环境因素限制,通常情况下会出现的情况是,所开发的应用在本地是可以比较健康的、符合预期的运行,但是在 FaaS 平台上,则会出现一些不可预测的问题;或者是在一些特殊的环境下,本地没有办法模拟线上环境,难以进行项目的开发和调试。
Serverless 应用的调试,一直都是备受诟病的,但是各个云厂商并没有因此放弃在调试方向的不断深入探索。以阿里云函数计算为例,其提供了在线调试、本地调试等多种调试方案。
在线调试
简单调试
所谓的简单地调试,就是在控制台来进行调试,以阿里云函数计算为例,可以在控制台通过执行按钮,进行基本的调试:
必要时候,也可以通过设置 Event 来模拟一些事件:
在线进行调试的好处是,可以使用线上的一些环境进行代码的测试。否则当线上环境拥有 VPC 等资源时,在本地环境是很难进行调试,例如数据库需要通过 VPC 来进行访问时,或者有对象存储触发器的业务逻辑等。
远程调试
端云联调本地除了一个通道服务容器,仍有一个函数计算容器,用来执行本地函数,远程的辅助函数只是单纯将远程流量发送到本地;但是在实际调试过程中,为了更加简单方便,还需要登录到实例中进行项目调试,此时可以选择使用远程调试功能进行调试,相对以端云联调,远程调试本地只有一个通道服务容器,执行过程全部依赖于线上,远程函数将执行结果返回;其整体架构简图如图 5.22 所示:
在远程调试中,用户通过 remote setup 指令搭建本地与远程的容器通道,并在远程新建一个与本地配置完全相同的函数。之后,通过通道服务,用户可以直接获取线上的 VPC 内网资源,比如 NAS,OSS 等等。用户还可以通过容器直接进入远程的函数计算环境,进行更加细致地调试。使用远程调试组件启动单步调试,用户只需在 remote setup 后,启动 IDE 的调试模式(当前仅支持 VSCode,Intellij)。使用 remote invoke 启动函数,此时即可发现程序运行到断点处。远程调试提供了登陆功能。在完成 s remote setup 后,可以通过代理容器远程登录到函数计算实例。通过查询当前代理容器的 ID:
然后可以进入容器实例:
直接登录远程实例即可(即线上的真实环境实例):
完整的操作流程如下图所示:
最佳实践案例
三步完成端云联调
远程调试可以通过三个非常简单的步骤快速实现:
步骤 1: 在已有的项目下,创建远程调试的辅助资源,开启远程调试模式:
s remote setup
;步骤 2: 在完成远程调试模式开启动作之后,通过
s remote invoke
或者线上的事件进行函数的触发,调试;步骤 3: 完成远程调试之后,通过
s remote clean
命令,对对因远程调试而产生的辅助资源进行清理;
断点调试
通过与常见的 IDE 进行结合,可以在常见的 IDE 上实现远程调试的断点调试。
VSCode 断点调试案例
步骤 1: 在已有的项目下,开启调试模式的远程调试能力:
$ s remote setup --config vscode --debug-port 3000
,命令执行完成功后, 本地的函数计算执行环境会阻塞等待调用(执行环境本质是一个 HTTP Server);此时若要进行断点调试,需要进行以下的操作在 VSCode 上进行相关的配置:Serverless Devs 开发者工具自动在工程目录下面生成
.vscode/launch.json
文件, 通过下图完成调试配置:步骤 2: 打开一个新的终端,通过
remote invoke
进行触发(例如s remote invoke
),回到 VSCode 界面,既可以进行断点调试了:调试完成后返回结果。
若要在调用的时候制定传入的 event 参数,可以使用
--event
,例如s remote invoke -h
步骤 3: 完成远程调试之后,通过
s remote clean
命令,对对因远程调试而产生的辅助资源进行清理;
Intelli 断点调试案例
步骤 1: 例如需要在 IDEA 下进行调试,可以在已有的项目下,开启调试模式的远程调试能力:
$ s remote setup --config idea --debug-port 3000
,命令执行完成功后, 本地的函数计算执行环境会阻塞等待调用(执行环境本质是一个 HTTP Server);此时若要进行断点调试,需要进行以下的操作在 IDEA 上进行相关的配置:
在菜单栏选择 Run… > Edit Configurations 。
新建一个 Remote Debugging 。
自定义调试器名称,并将端口配置为 3000 。
上述配置完成后,在 IDEA 编辑器侧边栏为函数代码增加断点,点击"开始调试"按钮。
步骤 2: 打开一个新的终端,通过
remote invoke
进行触发(例如s remote invoke
),回到 IDEA 界面,既可以进行断点调试了:调试完成后返回结果。
若要在调用的时候制定传入的 event 参数,可以使用
--event
,例如s remote invoke -h
步骤 3: 完成远程调试之后,通过
s remote clean
命令,对对因远程调试而产生的辅助资源进行清理;
端云联调
所谓的端云联调指的是在本地进行 Serverless 应用开发时,往往会涉及到一些线上资源,例如通过对象存储触发器触发函数执行,通过 VPC 访问数据库等,此时由于线上线下环境的不一致性,会让线下的开发、调试面临极大的挑战。Serverless Devs 团队通过搭建 Proxy 辅助函数的方法,将线上线下资源打通,可以快速帮助开发者在本地进行函数的开发与调试。
如图所示, Serverless Devs 开发者工具会根据开发者的函数的 yaml 文件配置,创建辅助服务和辅助函数(这个辅助服务和函数的配置跟您的服务和函数是相同的),并通过辅助服务和辅助函数实现线上线下的网络环境打通,以及完整的端云联调能力:
调用这个辅助函数, 流量会打回到本地的调试实例, 这个时候本地实例接受到 event 和 context 是真实来自线上的
本地调试的实例运行函数逻辑, 能直接利用辅助函数运行的那个容器, 可以直接访问 vpc 内网以及一些云服务的内网地址
具体的使用流程是:
执行
s proxied setup
来准备端云联调所需的辅助资源以及本地环境;对于无触发器的普通事件函数或者 http 触发器函数,准备工作完成后,启动另一个新的终端,切换到该项目路径下,执行
s proxied invoke
来调用本地函数;完成调试任务之后,可以执行
s proxied cleanup
清理端云联调所需的辅助资源以及本地环境;
除了通过命令行使用端云联调能力,也可以在 VSCode 等开发者工具中使用,例如:
最佳实践案例
三步完成端云联调
端云联调可以通过三个非常简单的步骤快速实现:
步骤 1: 在已有的项目下,创建端云联调的辅助资源,开启端云联调模式:
s proxied setup
;步骤 2: 在完成端云联调模式开启动作之后,通过
s proxied invoke
或者线上的事件进行函数的触发,调试;步骤 3: 完成端云联调之后,通过
s proxied clean
命令,对对因端云联调而产生的辅助资源进行清理;
断点调试
通过与常见的 IDE 进行结合,可以在常见的 IDE 上实现端云联调的断点调试。
VSCode 断点调试案例
步骤 1: 在已有的项目下,开启调试模式的端云联调能力:
$ s proxied setup --config vscode --debug-port 3000
,命令执行完成功后, 本地的函数计算执行环境会阻塞等待调用(执行环境本质是一个 HTTP Server);此时若要进行断点调试,需要进行以下的操作在 VSCode 上进行相关的配置:Serverless Devs 开发者工具自动在工程目录下面生成
.vscode/launch.json
文件, 通过下图完成调试配置:步骤 2: 打开一个新的终端,通过
proxied invoke
进行触发(例如s proxied invoke
,如果是事件函数也可以通过线上触发器进行触发,此时要注意将触发器临时指向辅助函数,详情参考proxied invoke 命令操作过程),回到 VSCode 界面,既可以进行断点调试了:调试完成后返回结果。
若要在调用的时候制定传入的 event 参数,可以使用
--event
,例如s proxied invoke -h
步骤 3: 完成端云联调之后,通过
s proxied clean
命令,对对因端云联调而产生的辅助资源进行清理;
Intelli 断点调试案例
步骤 1: 例如需要在 IDEA 下进行调试,可以在已有的项目下,开启调试模式的端云联调能力:
$ s proxied setup --config intellij --debug-port 3000
,命令执行完成功后, 本地的函数计算执行环境会阻塞等待调用(执行环境本质是一个 HTTP Server);此时若要进行断点调试,需要进行以下的操作在 IDEA 上进行相关的配置:
在菜单栏选择 Run… > Edit Configurations 。
新建一个 Remote Debugging 。
自定义调试器名称,并将端口配置为 3000 。
上述配置完成后,在 IDEA 编辑器侧边栏为函数代码增加断点,点击"开始调试"按钮。
步骤 2: 打开一个新的终端,通过
proxied invoke
进行触发(例如s proxied invoke
,如果是事件函数也可以通过线上触发器进行触发,此时要注意将触发器临时指向辅助函数,详情参考proxied invoke 命令操作过程),回到 IDEA 界面,既可以进行断点调试了:调试完成后返回结果。
若要在调用的时候制定传入的 event 参数,可以使用
--event
,例如s proxied invoke -h
步骤 3: 完成端云联调之后,通过
s proxied clean
命令,对对因端云联调而产生的辅助资源进行清理;
本地调试
命令行工具
就目前来看,大部分 FaaS 平台都会为用户提供相对完备的命令行工具,包括 AWS 的 SAM CLI,阿里云的 Funcraft,同时也有一些开源项目例如 Serverless Framework、Serverless Devs 等对多云厂商的支持等。通过命令行工具进行代码调试的方法很简单,以 Serverless Devs 为例,本地调试阿里云函数计算:
首先确保,本地拥有一个函数计算的项目,然后在项目下执行调试指令,例如在 Docker 中进行调试:
图 1.70: 通过命令行进行本地调试
编辑器插件
以 VScode 插件为例,当下载好阿里云函数计算的 VSCode 插件,并且配置好账号信息之后,可以在本地新建函数,并且在进行打点,之后可以进行断点调试:
图 1.71: 编辑器插件中进行调试
当函数调试完成之后,可以进行部署等操作。
其他调试方案
Web 框架的本地调试
在阿里云 FaaS 平台开发传统 Web 框架,以 Python 语言 Bottle 框架为例,可以增加:
并且对 run()方法进行条件限制(if __name__ == '__main__')
:
这样,可以在本地开发的同时,和传统开发思路一样,在本地进行调试。当部署到线上时,只需要在入口方法处填写index.app
,即可实现平滑的部署。
本地模拟事件调试
针对非 Web 框架,可以在本地构建一个方法,例如要调试一下对象存储触发器,可以是:
这样通过构造一个 event 对象,即可实现模拟事件触发。
版权声明: 本文为 InfoQ 作者【刘宇】的原创文章。
原文链接:【http://xie.infoq.cn/article/fcd4d0434dcfd45c9cf426a1c】。文章转载请联系作者。
评论