idea+openresty+lua开发环境搭建 (apisix)
前言:统一网关apisix自带插件不符合现有业务逻辑时,自定义开发插件可能会选择lua开发。而apisix是基于OpenResty构建的,即开发/Debug时需要OpenResty环境。
OpenResty简介
OpenResty(也称为ngx_openresty)是一个基于Nginx的全功能Web应用服务器,它通过集成了许多第三方模块和库,为Nginx提供了更多功能和扩展性。OpenResty使得开发人员能够使用Lua编程语言来扩展Nginx服务器的功能,从而更灵活地构建高性能的Web应用程序和服务。
以下是OpenResty的一些主要特点和组成部分:
-
Nginx核心: OpenResty使用Nginx作为底层服务器,继承了Nginx的高性能和可扩展性。Nginx是一个轻量级、高性能的Web服务器和反向代理服务器,广泛用于构建高流量的网站和应用。
-
Lua支持: OpenResty集成了Lua编程语言,允许开发人员通过Lua脚本扩展和定制Nginx的功能。Lua是一种轻量级、高效的脚本语言,它可以用于处理请求、响应、路由、访问控制等各种服务器端任务。
-
第三方模块和库: OpenResty提供了丰富的第三方模块和库,用于扩展Nginx的功能。这些模块可以处理缓存、认证、请求处理、流量控制、WebSockets等多种任务。
-
高性能代理: OpenResty支持高性能的反向代理,能够有效地负载均衡和处理大量的并发请求。
-
Lua脚本控制: 使用Lua脚本,可以动态地配置Nginx,使得开发人员能够在请求处理阶段执行自定义逻辑。这可以用于构建复杂的应用逻辑和路由规则。
-
缓存和加速: OpenResty具有强大的缓存和加速功能,可以缓存静态内容,减轻后端服务器的负担,提高响应速度。
-
WebSockets支持: OpenResty支持处理WebSockets协议,使得构建实时通信的应用变得更加简单。
-
动态模块加载: OpenResty支持动态地加载和卸载模块,不需要重新编译或重启服务器。
-
总之,OpenResty是一个强大的服务器平台,它将Nginx和Lua集成在一起,提供了高性能、灵活性和扩展性,适用于构建高性能的Web应用程序和服务。
OpenResty环境搭建:
###1.环境准备
-
openresty下载:https://github.com/openresty/openresty/releasesDownload zip包 解压到windows使用目录即可
-
目录结构如下:
-
openresty框架中,支持直接在location中运行lua代码块/在location中定位.lua文件,两种方式的使用方法参考:openresty快速入门
2.运行方式
- 访问ip+port+path
eg:localhost:9099/discovery
IDEA环境搭建:
1.环境准备:
- idea 插件安装: EmmyLua,Nginx Support
- 大致思路:配置nginx_server(即openresty路径下nginx) 在idea上编写lua脚本,通过ant将代码及配置文件复制到openresty路径下
2.环境配置
1.创建maven工程:
2.配置nginx为openresty的nginx的启动文件
3.配置ant:
注:此处主要复制lua脚本到openresty路径下。
build.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<!-- 项目路径 -->
<project name="openResty" default="copy" basedir="E:\work\openresty-1.21.4.2-win64">
<description>
run nginx-server
</description>
<!-- set global properties for this build -->
<property name="openresty-home" location="E:\work\openresty-demo\src"/>
<property name="resource-path" location="${openresty-home}/${ant.project.name}"/>
<property name="target-src" location="${basedir}/lua"/>
<target name="clean" depends="">
<echo>清理openresty目录 ${dist}下的conf,logs,janus,januslib</echo>
<delete file="${target-src}\discovery.lua"/>
<delete file="${target-src}\nacos.lua"/>
<delete file="${target-src}\test.lua"/>
</target>
<target name="copy" description="generate the distribution" >
<echo>复制安装文件</echo>
<copy todir="${target-src}">
<fileset dir="${openresty-home}"></fileset>
</copy>
</target>
</project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
4.ant配置build.xml
5.将ant插件与nginx插件关联起来:
6.配置nginx 日志路径,以便在idea控制台查看
3.运行方式
1.手动执行ant命令,查看效果,正常情况下可以看到idea src目录下代码被copy到lua路径下
2.访问ip+port+path
eg:localhost:9099/discovery
3.在本地开发时,只需重启nginx服务,再重新访问步骤2的地址即可。
idea+openresty+lua开发环境搭建_idea openresty-CSDN博客
vscode lua插件_OpenResty(lua) 调试-CSDN博客
luaIde 调试openresty
调试视频 提取码:o3rk
1.创建一个项目 如果已存在项目忽略

2.项目中创建src目录
-
(src目录可是任意名字 示例中将src放入根目录中,您也可以放到其他目录,src目录为lua脚本根目录)
-
如果已存在项目忽略

3.配置项目

前三步可以忽略根据自己的项目来定即可.
4.用vscode 打开项目文件夹 示例中的项目文件夹为openresty_test
5.打开一个lua文件以启动luaide插件(演示中没有lua文件,所以创建一个文件 test.lua)
6.根据提示将调试文件拷贝到src目录中
-
选择LuaDebugOpenrestyJit 后缀选择.lua
-
由于luaide支持多种lua框架的调试所以会有很多不同的后缀名,openresty 选择.lua即可
-
这一步操作后 LuaDebugOpenrestyJit.lua 拷贝到src 下






7.点击vscode左侧luaide按钮选择[打开luaide最新调试文件所在文件夹]


-
linux 找到socketLibOpenRestylinux目录下的 socket.so 拷贝到openresty_test(项目根目录)
-
mac 找到socketLibOpenRestymac目录下的 socket.so 拷贝到openresty_test(项目根目录)
-
windows 找到socketLibOpenRestywindows目录下的 socket.so 拷贝到openresty_testlualib(项目根目录lualib)
8.在luaide配置中设置脚本根目录 选择settings(中文为设置)
-
搜索luaide.scriptRoots 并进行设置 然后重启vscode
-
这里注意vscode 的设置配置分为
-
1.用户设置
-
2.工作空间设置 示例中添加到了 工作空间设置 设置后重启vscode f1 reloadwindow
-
3.文件夹设置
-
修改配置后重启vscode f1 reload window

9.添加调试代码以启动调试

10.添加调试配置




11.启动调试 nginx -p pwd
/ -c conf/nginx.conf (启动调试根据自己项目情况自行启动.这里只是演示)
12.访问页面

调试演示结束!
使用 ZeroBrane Studio 调试 OpenResty 和 Nginx Lua 脚本
ZeroBrane Studio已经用于调试各种 Lua 引擎——游戏框架(例如Corona、Gideros、Moai、Love2d)、家庭自动化设备、wireshark 脚本、Adobe Lightroom 插件等等——但还有一些 Lua 环境我还没有尝试过。其中之一就是 OpenResty/Nginx Lua 脚本。OpenResty是一个基于 nginx 构建的 Web 应用服务器,nginx 是一个非常快速的 Web 服务器,它为各种后端(Redis、Memcached、MySQL、 HTTP服务器等)提供非阻塞 IO ,并支持 Lua 作为其脚本语言。
我首先尝试使用 OpenResty 提供的非阻塞套接字API,但无法进行调试,因为原本应该阻塞的套接字调用返回得太早,从而破坏了应用程序中的调试器与IDE 之间的交互。根据 OpenResty 软件包维护者张亦春 (agentzh) 的建议,我尝试使用 ZeroBrane Studio 使用的同一个 luasocket 库,并成功了。您可以按照以下步骤亲自尝试:
ZeroBrane Studio 配置。
1. 获取ZeroBrane Studio。这些说明适用于 Windows,但调试也适用于 Linux 和OSX 。
2.启动ZBS(zbstudio.exe
或zbstudio.sh
)并启动调试器Project | Start Debugger Server
。
OpenResty 配置。
1. 我使用一个非常基本的配置(<NGINX>/conf/nginx.conf
):
worker_processes 1;
events {
worker_connections 1024;
}
http {
lua_package_path '<ZBS>/lualibs/?/?.lua;<ZBS>/lualibs/?.lua;;';
lua_package_cpath '<ZBS>/bin/clibs/?.dll;;';
server {
location /hellolua {
default_type 'text/plain';
content_by_lua_file 'lua/content.lua';
}
}
}
确保将其替换<ZBS>
为 ZeroBrane Studio 的实际路径。如果您在OSX 上运行,请将其替换?.dll
为?.dylib
;如果您在 Linux 上运行,请根据您的平台将其替换bin/clibs/?.dll
为bin/linux/x86/clibs/?.so
或。bin/linux/x64/clibs/?.so
2.创建我们要调试的文件(<NGINX>/lua/content.lua
),它可能如下所示:
require('mobdebug').start('192.168.1.22')
local name = ngx.var.arg_name or "Anonymous"
ngx.say("Hello, ", name, "!")
ngx.say("Done debugging.")
require('mobdebug').done()
请注意,start()
调用时会获取运行 IDE 的计算机的 IP 地址。默认情况下,它使用“localhost”,但由于您的 nginx 实例正在该地址运行,因此您需要指定运行IDE的计算机的 IP 地址(在本例中为192.168.1.22
)。
3. 在IDE中打开此文件(<NGINX>/lua/content.lua
) ,然后通过转到将项目目录设置为文件夹。lua
Project | Project Directory | Set From Current File
脚本调试。
现在启动 nginx 并访问http://localhost/hellolua。如果一切正常,您应该会看到 ZeroBrane Studio 被激活,并且绿色箭头指向第二行(类似于上面的屏幕截图)。现在您可以设置断点、单步执行代码、查看堆栈等等。
您还可以转到远程控制台并在那里运行任何 ngx 命令。例如,如果您运行ngx.say("Message from console")
(如屏幕截图所示),脚本完成后,您将在输出中看到此文本。
如果您在开始调试时在 Nginx 日志中收到“尝试跨越 C 调用边界”错误,请尝试使用较新的 ZeroBrane Studio(0.70+),因为它包含多项改进,使调试能够与较新版本的 OpenResty 配合使用。
OpenResty 配置用于远程调试。
仅当您配置 OpenResty/Nginx 进行远程调试时,且 Nginx 运行在一台机器上,而 ZeroBrane Studio 运行在另一台机器上时,才需要执行以下步骤。当两者在同一台机器上运行时,Nginx 将使用 ZeroBrane Studio 附带的模块,因为这些模块被lua_package_path
和指令引用lua_package_cpath
。
1. 复制调试器 ( mobdebug.lua
) 和套接字文件。前往<ZBS>/lualibs/mobdebug/
并复制mobdebug.lua
到<NGINX>/lua/mobdebug.lua
;也复制<ZBS>/lualibs/socket.lua
到<NGINX>/lua/
。完成所有这些操作后,lua
文件夹的内容将如下所示:
./
content.lua
mobdebug.lua
socket.lua
2. 复制<ZBS>/bin/clibs/socket/core.dll
到<NGINX>/socket/core.dll
(core.dylib
并且文件也core.so
位于该文件夹中)。bin
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 标记。
设置完成后的项目结构如下
在 /usr/local/apisix
下新建 lualib
目录,下载 mobdebug.lua 代码,放在 lualib
目录中,效果如下
然后参考配置项目依赖库,把 lualib
设置为项目的 lib
,设置完成后效果如下
这里也可以在 lualib
中继续添加 emmylua_ngx.lua ,用于补充openresty函数提示专用库,方便在写代码的时候获得更多的提示。
0x03 调试
新建 Lua Remote(Mobdebug),具体过程参考:emmylua.github.io/run/remote.…
添加完成后效果如下
在需要 debug 的地方添加如下函数
require("lualib.mobdebug").start("127.0.0.1", 8172)
在 IDEA 中启动 remote debug 进程,效果如下
在 IDEA console 中会出现 debug 进程启动的消息,这相当于启动了一个进程,监听 8172 端口,这个进程属于 IDEA 的,与 APISIX 没什么关系,查看以下监听 8172 端口的进程信息
简单理解一下, 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 效果如下
还可以计算表达式
可以单步调试,进入或者跳出函数。比如 230 行函数
local ok, err = balancer.set_current_peer(server.host, server.port)
调用了 set_current_peer
函数,当 debug 到这行时,按 F7 进入该函数
0x04 尾声
本文介绍的 APISIX 动态调试功能主要用于学习源码,了解其运行过程,提高学习效率。希望能帮助到和我一样,习惯了动态调试,刚开始接触 APISIX/OpenResty/Kong 等相关技术栈的小伙伴。