APISIX Runtime Debug/动态调试

4,126 阅读3分钟

APISIX 运行时调试

0x00 说明

本文基于 APISIX 2.5,IDEA 2021.1,IntelliJ-EmmyLua 插件 1.3.6.215,MobDebug 0.709。

0x01 环境

我是在 CentOs 7 系统中进行开发的,首先搭建APISIX 开发环境,根据 APISIX 的官方文档,先安装依赖,然后通过源码包安装 APISIX

APISIX 的安装位置是 /usr/local/apisix,开发环境搭建完成后, cd 到 该目录下,可以通过 ./bin/apisix start 命令启动 APISIX。

在 CentOs 7 中安装 IDEA 和 Emmyua 插件的过程不赘述。

0x02 项目

用 IDEA 打开 /usr/local/apisix,根据 EmmLua 教程,首先设置项目结构,将 /usr/local/apisix 设置为项目根目录

必须将源码的根目录设置为 Sources 目录。

具体做法是打开菜单 File -> Project Structure 打开 Project Structure 设置面板,点击右侧的 Add Content Root 来添加你的源码根目录,然后点击 Mark as Sources 标记。

设置完成后的项目结构如下

project-structure.png

/usr/local/apisix 下新建 lualib目录,下载 mobdebug.lua 代码,放在 lualib 目录中,效果如下

mobdebug.png

然后参考配置项目依赖库,把 lualib 设置为项目的 lib,设置完成后效果如下

lualib1.png

lualib2.png

这里也可以在 lualib 中继续添加 emmylua_ngx.lua ,用于补充openresty函数提示专用库,方便在写代码的时候获得更多的提示。

0x03 调试

新建 Lua Remote(Mobdebug),具体过程参考:emmylua.github.io/run/remote.…

添加完成后效果如下

remote-debug.png

在需要 debug 的地方添加如下函数

require("lualib.mobdebug").start("127.0.0.1", 8172)

在 IDEA 中启动 remote debug 进程,效果如下

debug-on.png

在 IDEA console 中会出现 debug 进程启动的消息,这相当于启动了一个进程,监听 8172 端口,这个进程属于 IDEA 的,与 APISIX 没什么关系,查看以下监听 8172 端口的进程信息

listen-8172.png

简单理解一下, debug 的过程相当于在本地启动一个进程,监听 8172 端口。当 APISIX 运行到 debug 函数的时候,让当前协程挂起,然后调用 lualib/mobdebug.lua 模块将中的功能,将当前函数相关的变量,堆栈信息通过 LuaSocket 发送到 127.0.0.1:8172,即本地的 8172 端口,监听 8172 端口的进程接受到这些信息之后,在 IDEA 中展示。

启动 APISIX,命令如下

./bin/apisix start

在这里需要注意,提前配置好 APISIX 中的 route upstream 等信息,启动 APISIX 后,构造请求,访问 APISIX,触发代码运行到需要 debug 的地方。

比如我配置的 route 如下

{
    "id": "1",
    "update_time": 1611044949,
    "uri": "/foo/*",
    "status": 1,
    "priority": 0,
    "plugins": {},
    "upstream": {
        "nodes": {
            "127.0.0.1:1980": 2,
            "127.0.0.1:1981": 1
        },
        "type": "roundrobin"
    },
    "create_time": 1611044129
}

在 upstream 中配置了 2 个 node,当我访问

curl 127.0.0.1:9080/foo/1

的时候,APISIX 的代码会运行到 /usr/local/apisix/apisix/balancer.lua 模块的第 230 行,即我添加 debug 函数的地方。

debug 效果如下

debug1.png

debug2.png

还可以计算表达式

evaluate.png

可以单步调试,进入或者跳出函数。比如 230 行函数

local ok, err = balancer.set_current_peer(server.host, server.port)

调用了 set_current_peer 函数,当 debug 到这行时,按 F7 进入该函数

step-into.png

0x04 尾声

本文介绍的 APISIX 动态调试功能主要用于学习源码,了解其运行过程,提高学习效率。希望能帮助到和我一样,习惯了动态调试,刚开始接触 APISIX/OpenResty/Kong 等相关技术栈的小伙伴。