导读:在应用开发过程中,或者开发完成后,若出现执行结果不符合我们的预期时,通常需要进行一定的调试工作。但是在 Serverless 架构下,调试工作往往会受到一些环境因素限制,如所开发的应用在本地是比较健康的、且符合预期的运行,但是在 FaaS 平台上,出现了一些问题;或者是在某些特殊的环境下,本地没有办法模拟线上环境,难以进行项目的开发和调试怎么办?

概述

本文将借助 Serverless Devs 工具,对函数计算 (FC)应用的断点调试步骤进行详细指导,手把手带你实现 Serverless 的断点调试,并从以下四个方面为你厘清“硬核调试”的脉络步骤,干货满满:

一、概述部分介绍了调试能力的重要性,以及当前阿里云函数计算(FC)所能提供的调试能力;

二、调试之旅罗列了关于 “使用 Serverless Devs 在不同 IDE 中进行断点调试” 的详细步骤;

三、总结部分客观诉说断点调试的待改进之处;

四、附录则为各位开发者汇总了断点调试操作的详细动图。

在 Serverless 应用架构下,调试能力往往是应用开发者所十分关注的问题,它决定着程序的开发效率。Hackernoon 在关于 Serverless(无服务器)的业界调研报告指出:迄今为止,Debugging(调试)仍旧是 Serverless 落地最大的痛点与挑战。

报告《Top 5 Serverless Trends》:https://hackernoon.com/top-5-serverless-trends-in-2020-wd1m3t8g

调试能力主要包含两种,一是运行程序的能力;二是断点调试能力。前者是调试的基础能力,可以判帮助开发者判断程序能否正常运行,验证程序运行结果的正确性;后者是调试的高级能力,能够帮助用户方便定位到导致程序运行出错或者不符合预期的位置。

目前业界已有的 Serverless 应用调试手段,主要是在本地模拟云端执行环境进行本地调试;或者将应用部署到云端运行后基于日志进行调试。然而,本地调试无法模拟云端的网络环境,云端调试又缺乏本地的灵活性。为了能够克服这些缺陷,将 Serverless 应用调试做到开箱即用,阿里云函数计算团队经过一番探索,开发出了一套业界创新的调试工具,全方位提供本地调试以及端云联调能力。

本文所提到的本地调试工具,均提供断点调试能力,且与 Serverless 应用程序开发规范完全兼容,下面我们一起看一下关于断点调试的具体操作步骤。

调试之旅

断点调试步骤总结为如下流程,下面我将带领各位围绕这四个步骤,开启一场断点调试之旅:

  • 启动 Serverless 应用
  • 启动断点调试器
  • 开始断点调试
  • 结束断点调试

1、前置操作

在开始进行调试之前,需要进行一些前置操作,本文将前置操作分为通用前置操作以及端云联调附加的前置操作

2、参数引入

完成以上前置条件的准备后,我们先了解一下调试指令中与断点调试所相关的具体参数:

-c, --config [vscode/pycharm/intellij]   [Required] Select which IDE to use when
debugging and output related debug
config tips for the IDE. value:
vscode/pycharm/intellij -d, --debug-port number [Required] Specify the local function
container starting in debug mode, and
exposing this port on localhost --debug-args string [Optional] Additional parameters that
will be passed to the debugger --debugger-path string [Optional] The path of the debugger on
the host --tmp-dir string [Optional] The temp directory mounted to
'/tmp' , default:
'./.s/tmp/invoke/serviceName/functionName/'

使用断点调试时,--config 参数以及 --debug-port 参数是必要的:

  • --config 会指定断点调试的 IDE 环境,目前支持 VSCode、Pycharm 、Intellij 三种。
  • --debug-port 会指定调试的监听端口。

另外,其余三种参数是可选的:

  • --debug-args 会自定义程序启动时的调试参数,不指定时默认的调试参数可以参考文末附录部分
  • --debugger-path 会将本地指定路径挂载到程序运行环境的 /tmp/debugger_file之中。
  • --tmp-dir 会将本地指定路径挂载到程序运行环境中的 /tmp 目录上,在调试时,程序写入 /tmp 的结果文件则会在映射到本地目录,用于验证结果是否符合预期。

3、实操演练

1)VSCode

使用 VSCode 进行断点调试时,流程十分简单,下面我们将断点调试场景分为 Event 函数调试和 Http 函数调试两种,分别进行介绍。

  • 调试 Event 函数:

step1:首先启动 Serverless 应用,打开终端,进入目标项目下,输入启动指令:

# 本地调试
$ s local invoke --config vscode --debug-port 3000 # 端云联调
$ s proxied setup --config vscode --debug-port 3000

启动指令执行后,本地的函数计算执行环境会有一定阻塞,我们需要等待调用;与此同时当前项目会生成 .vscode/launch.json 文件,该文件是基于 VSCode 进行调试的配置文件,若该文件已经存在,那么启动指令会打印相应配置文本,如下图所示,需要利用这部分内容覆盖已有 .vscode/launch.json 中的内容。



.vscode/launch.json 更新内容示例

step2:启动断点调试器,打开 VSCode 界面,然后打开 s.yml 中 codeUri 所存放的源代码,为其打上断点,接着点击开始调试按钮,具体执行如下图所示。



** VSCode 启动调试器示意图**

对于本地调试而言,启动调试器后,程序便已经启动,此时就可以开始进行我们的断点调试工作了。如果是端云联调的话,启动调试器后,在启动指令终端页面,会出现 "Debugger attached." 字段,这时说明调试器也已启动成功,正在等待被调用,接下来我们继续进行如下步骤即可。

step3:开始断点调试:打开一个新的终端页面,输入调用指令 s proxied invoke --event "hello"后,程序启动,断点调试开始。

step4:结束断点调试:调试结束后,主动关闭断点调试器。端云联调场景下,会创建一系列辅助函数资源,因此调试完成后,这里需要进行辅助资源释放,防止额外的费用产生,只需执行 s proxied cleanup 即可释放辅助资源。

  • 调试 php7.2 Event 函数

php7.2 runtime 的本地调试 IDE 建议使用 VSCode,其断点调试步骤与其他语言有一定差异性,因此单独进行介绍。目前 php7.2 runtime 不支持端云联调断点调试。

step1:首先启动 Serverless 应用,打开终端,进入目标项目下,输入启动指令 s local invoke --config vscode --debug-port 3000

与之前不同的是,Event 函数启动指令执行完成后,并不会出现阻塞的情况,而是会直接执行成功,同时在当前项目下会生成 .vscode/launch.json 文件,如前文所述。

step2:启动断点调试器,打开 VSCode 界面,然后打开 s.yml 中 codeUri 所存放的源代码,为其打上断点,接着点击开始调试按钮,具体执行如下图所示。



step3:开始断点调试:打开一个新的终端页面,再次输入启动指令 s local invoke --config vscode --debug-port 3000后,程序启动,断点调试开始。

step4:结束断点调试:调试结束后,主动关闭断点调试器。

  • 调试 Http 函数

端云联调中对 Http 函数的调试方式实际上与 Event 函数相同,因此不再赘述,本节我们主要介绍下本地调试关于 Http 函数应该如何进行调试。

step1:启动 Serverless 应用,首先,打开终端,进入目标项目下,输入启动指令 s local start --config vscode --debug-port 3000,启动指令执行后,本地的函数计算执行环境会阻塞等待调用,并打印访问 http 函数的 url 字段。

step2:启动断点调试器:打开 VSCode 界面,然后打开 s.yml 中 codeUri 存放的源代码,为其打上断点,接着点击开始调试按钮,如图所示。此时在启动指令终端页面,会出现 "Debugger attached." 字段,说明调试器启动成功,等待被调用。



** VSCode 启动调试器示意图**

step3:开始断点调试:可以通过 curl 指令、浏览器等方式访问 Http 函数的 URL,此时程序启动,断点调试开始。

step4:结束断点调试:调试完成后,主动关闭断点调试器,然后在启动指令终端页面,执行 Ctrl+C 即可退出调试进程。

  • 调试 php7.2 Http 函数

php7.2 runtime 的本地调试 IDE 建议使用 VSCode,其断点调试步骤与其他语言有一定差异性,因此单独进行介绍。目前 php7.2 runtime 不支持端云联调断点调试。

step1:首先启动 Serverless 应用,打开终端,进入目标项目下,输入启动指令 s local start --config vscode --debug-port 3000,启动指令执行后,会在当前项目下会生成 .vscode/launch.json 文件,如前文所述,同时项目会阻塞住,此时需要执行 Ctrl+C 退出。

step2:启动断点调试器,打开 VSCode 界面,然后打开 s.yml 中 codeUri 所存放的源代码,为其打上断点,接着点击开始调试按钮,具体执行如下图所示。



step3:开始断点调试:打开一个新的终端页面,再次输入启动指令 s local start --config vscode --debug-port 3000后,本地的函数计算执行环境会阻塞等待调用,并打印访问 http 函数的 url 字段,可以通过 curl 指令、浏览器等方式访问 Http 函数的 URL,此时程序启动,断点调试开始。

step4:结束断点调试:调试完成后,主动关闭断点调试器,然后在启动指令终端页面,执行 Ctrl+C 即可退出调试进程。

2)Intellij

基于 Intellij 进行断点调试时,针对不同语言需要手动在 IDE 中配置相应地断点调试器,由于使用 Intellij 开发最多的语言是 Java,同时更换 IDE 后,唯一不同的步骤只有“启动断点调试器”,因此接下来我们将以本地调试 Java Event 函数为例,对“启动断点调试器”步骤进行详细说明。

step1:启动 Serverless 应用: 由于 Java 是编译型语言,因此在开始前需要对程序进行打包,本文示例会使用 mvn package 对函数打包,然后执行启动指令 s local invoke --config intellij --debug-port 3000

step2:启动断点调试器

打开 Intellij 界面,在菜单栏依次选择 Run -> Edit Configurations

随后如下图所示,新建一个 Remote JVM Debug



新建 Remote JVM Debug

接着,自定义调试器名称,并将端口设置为 3000,如下图所示。



Intellij 调试器配置

最后,打开 s.yml 中 codeUri 存放的源代码,为其打上断点,接着点击开始调试按钮,如图所示。



Intellij 启动断点调试器

3)Pycharm

当前只有本地调试能够在 Pycharm 中进行断点调试操作,支持的运行时有 python2.7 和 python3两个版本。在 Pycharm 中进行断点调试时,不仅需要在 IDE 中配置断点调试器,还需要对使用者的源码进行侵入式修改,由于操作步骤内容与常规内容有所不同,接下来我们详解一下这部分的调试步骤。

step1:启动 Serverless 应用:首先,打开终端,进入目标项目下,输入启动指令:

# event 函数
$ s local invoke --config pycharm --debug-port 3000 # http 函数
$ s local start --config pycharm --debug-port 3000

与之前不同的是,Event 函数启动指令执行完成后,并不会出现阻塞的情况,而是会直接执行成功。此时就需要记录 "Tips for PyCharm remote debug" 内容,具体内容示例如图所示,记录完成后,如果是 Http 函数,则输入 Ctrl+C 退出启动程序。



Tips for PyCharm remote debug 内容示例

step2:接下来启动断点调试器:启动断点调试器主要包含 IDE 断点调试器配置和源码更新两部分。

首先,打开 pycharm 界面,在菜单栏依次选择 Run -> Edit Configurations

接下来如图中所示,新建一个 Python Debug Server



新建 Python Debug Server

随后设置自定义调试器名称,并基于图五中获取的内容配置 IDE host namePort 以及 Path mappings 这三个调试器配置的详情,如图中所示。



pycharm 调试器配置

随后打开 s.yml 中 codeUri 存放的源代码,将例图中(Tips for PyCharm remote debug 内容示例)的代码内容粘贴到代码开头,然后按需在源码指定位置打上断点,接着点击开始调试按钮,具体操作如图 (pycharm 启动断点调试器)所示。



Tips for PyCharm remote debug 内容示例



pycharm 启动断点调试器

step3:开始断点调试:打开终端,并进入目标项目,执行启动指令,p.S.此时可以不用带上断点调试的相关参数。

# event 函数
$ s local invoke # http 函数
$ s local start

Event 函数启动指令执行后会直接进入断点调试阶段;Http 函数启动指令执行后,可以先通过 curl 指令、浏览器等方式访问 Http 函数的 URL,此时程序会启动,断点调试就开始了。

step4:结束断点调试:调试完成后,主动关闭断点调试器,对于 Http 函数而言,在启动指令终端页面,需执行 Ctrl+C 方可退出调试进程。

结语

Serverless 应用的调试虽然备受诟病,但是各个云厂商并没有因此放弃在调试方向的不断深入探索。以阿里云函数计算为例,目前支持提供在线调试、本地调试、端云联调等多种调试方案。而 Serverless Devs 工具所提供的应用调试能力也十分全面了。

上文是我所分享的一些实操经验,但是在过程中也发现了一些待改进的点,如:

  • 断点调试步骤繁琐,需要在多个页面来回切换,如果能将工具集成到 IDE,以插件化形态供所用户使用,简化流程,那么体验感会大幅提升。
  • 断点调试模式下的热更能力:Http 函数的断点调试过程中,并不支持代码热更新,每次修改完代码后,都需要重新执行一遍断点调试流程,体验不太流畅。
  • 断点调试能力目前还未全面覆盖所有 Runtime,例如 custom runtime 不支持断点调试,php runtime 不支持端云联调断点调试等。

希望本文对你有些帮助。

附录

默认调试参数

Runtime Default Debug Args
nodejs 6 --debug-brk=${debugPort}
nodejs 8/10/12/14 --inspect-brk=0.0.0.0:${debugPort}
python 2.7/3 -m ptvsd --host 0.0.0.0 --port ${debugPort} --wait
java 8/11 -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=${debugPort}
php7.2 remote_enable=1 remote_autostart=1 remote_port=${debugPort} remote_host=${ip.address()}

更多内容关注 Serverless 微信公众号(ID:serverlessdevs),汇集 Serverless 技术最全内容,定期举办 Serverless 活动、直播,用户最佳实践。

硬核调试实操 | 手把手带你实现 Serverless 断点调试的更多相关文章

  1. 硬核机器学习干货,手把手教你写KNN!

    机器学习相关概念 人工智能.机器学习和深度学习的关系 在探讨算法之前,我们先来谈一谈什么是机器学习.相信大家都听说过AlphaGo:2016年3月,AlphaGo与围棋世界冠军李世石进行围棋人机大战, ...

  2. Zend Studio集成Xdebug断点调试详解

    转自:http://www.softown.cn/post/115.html Xdebug是PHP开发中两个常用的断点调试工具之一(另一个为Zend Debugger). 现在,我们在Zend Stu ...

  3. sbt结合IDEA对Spark进行断点调试开发

    笔者出于工作及学习的目的,经常与Spark源码打交道,也难免对Spark源码做修改及测试.本人一向讲究借助工具提升效率,开发Spark过程中也在摸索如何更加顺畅的对源码进行调试. Spark基于Sca ...

  4. JavaScript调试技巧之断点调试

    首先,在各个浏览器中,断点调试支持的最好的当然是Firefox,Firefox不仅可以使用Firebug调试页面js脚本,还可以用高级调试工具例如JavaScript Debugger (Venkma ...

  5. [Android Studio 权威教程]断点调试和高级调试

    好了开始写一个简单的调试程序,我们先来一个for循环 ? 1 2 3 4 5 6 7 8 <code class="language-java hljs ">for ( ...

  6. delphi 2010 动态链接库DLL断点调试

    DELPHI 2010 动态链接库DLL断点调试 马根峰 (广东联合电子服务股份有限公司,广州 510300) 摘要:本文详细介绍了Delphi 2010中的动态链接库DLL断点调试技术 关键词:DE ...

  7. ###Android 断点调试和高级调试###

    转自:http://www.2cto.com/kf/201506/408358.html 有人说Android 的调试是最坑的,那我只能说是你不会用而已,我可以说Android Studio的调试是我 ...

  8. Paip.断点调试MYSQL存储过程跟函数的解决方案大法

    Paip.断点调试MYSQL存储过程跟函数的解决方案大法 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn ...

  9. ESP8266 NodeMCU小白手把手入门(实操篇)以土壤湿度和DHT传感器为例讲解读取传感器的值

    物联网使得现实世界中的实体和数字世界比以往任何时候都更紧密地联系在一起.NodeMCU作为其中的一个重要设备,作用之一就是与传感器相连以实现万物互联通讯.这篇关于NodeMCU的实操篇以土壤湿度传感器 ...

  10. 小编亲身实操,教你配置phpstorm与xdebug的调试配置,不成功你骂我

    开发php,还是找个专业的Ide较好,vscode毕竟在php上不专业,需要下载各种插件才行,还不支持多线程调试,因此小编下载了phpstorm,打算以后用phpstorm来开发php项目,断点调试代 ...

随机推荐

  1. [CF1854C] Expected Destruction

    题目描述 You have a set $ S $ of $ n $ distinct integers between $ 1 $ and $ m $ . Each second you do th ...

  2. [ABC284G] Only Once

    Problem Statement For a sequence of length $N$, $A = (A_1,A_2,\dots,A_N)$, consisting of integers be ...

  3. [USACO2007FEB S]Silver Lilypad Pond

    题目描述 为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘.这个长方形的池子被分成 了M行N列个方格(1 ≤ M, N ≤ 30).一些格子是坚固得令人惊讶的莲花,还有一些格子是 岩石,其余的只是 ...

  4. 关于yolov3在训练自己数据集时容易出现的bug集合,以及解决方法

    早先写了一篇关于yolov3训练自己数据集的博文Pytorch实现YOLOv3训练自己的数据集 其中很详细的介绍了如何的训练自定义的数据集合,同时呢笔者也将一些容易出现的bug写在了博文中,想着的是可 ...

  5. 从Redis读取.NET Core配置

    在本文中,我们将创建一个自定义的.NET Core应用配置源和提供程序,用于从Redis中读取配置.在此之前,您需要稍微了解一些.NET Core配置提供程序的工作原理,相关的内容可以在Microso ...

  6. 操作系统大作业:在Linux环境下模拟实现简单命令解释器(代码部分)

    好家伙   1. 题目要求 一.   课程设计(大作业)目的 熟悉Linux编程环境,加强对Linux命令的理解及函数的运用,完成一个操作系统的部分系统的设计过程.编码.调试,锻炼实际应用能力. 二. ...

  7. Python——Html(表格<table>, <tr>,<td>,<th>、表单<form>、自定义标签<div>和<span>)

    一.表格<table>, <tr>,<td>或<th> <table> 元素是 HTML 中用于创建表格的主要标记.表格是一种用于展示数据的 ...

  8. Python——第一章:用户交互

    变量 = input(提示语)首先会在屏幕中显示出提示语, 用户输入内容. 然后把用户输入的内容交给前面的变量 案例1: a = input("请输入第一个数字:") #括号里是提 ...

  9. 一文读懂Spring框架中Bean的生命周期

    我们先来聊聊bean的生命周期: bean的生命周期图: AbstractAutowireCapableBeanFactory的docreateBean()方法(简单描述):  1.可以根据源码的时候 ...

  10. vue3 + element-plus 的 upload + axios + django 文件上传并保存

    之前在网上搜了好多教程,一直没有找到合适自己的,要么只有前端部分没有后端,要么就是写的不是很明白.所以还得靠自己摸索出来后,来此记录一下整个过程. 其实就是不要用默认的 action,要手动实现上传方 ...