如何在 K8s 环境中自动管理网关服务器(使用 OpenResty Edge)
调试
lijunlong , 2021 年 4 月 30 日(创建于 2013 年 10 月 6 日)您应该始终查看 Nginx 的错误日志文件(由 nginx.conf
中的 error_log
指令指定)以查找任何错误或警告。
如果您在 Lua 开发期间更喜欢将常见的 Lua 错误重定向到 HTTP 响应主体,您可以在 Lua 代码的顶层放置一个 Lua pcall 调用以捕获并重定向任何 Lua 异常。但请记住,并非所有错误都可以通过这种方式捕获,因为您可能在发送响应时出现错误,那么不可能将这些错误放入响应主体中。
在 Lua 代码开发期间,您可以暂时禁用 Lua 代码缓存,这样您就不必重新加载 Nginx 服务器才能使您的(外部)Lua 代码更改生效。
此外,强烈建议遵循测试驱动开发工作流程。例如,Lua Resty Redis 库 使用 Test::Nginx 测试脚手架来驱动其(声明式)测试套件。
如果您使用的是 Linux,则有许多基于 systemtap 的实时分析工具,可用于以各种方式检查正在运行的 Nginx 工作进程。
https://github.com/agentzh/nginx-systemtap-toolkit
您可以在 stap++ 项目中找到其他工具
https://github.com/agentzh/stapxx
这些工具不仅可以调试功能问题,还可以对在线服务器进行性能分析,以找出性能瓶颈。
调试内存问题
由 OpenResty 未维护的第三方 Lua 库或第三方 NGINX C 模块可能会出现内存问题,因为它们可能没有经过标准 OpenResty 组件的相同严格测试。在极少数情况下,标准 OpenResty 组件也可能出现内存问题。为了调试导致段错误或由于内存损坏导致软件行为出现奇怪的非确定性问题的此类内存问题,我们可以使用 Valgrind 来可靠地找到问题的真正罪魁祸首,前提是这些问题相对容易重现。
为了最大限度地提高 Valgrind 的 memcheck 工具的有效性,我们至少应该禁用 NGINX 核心中的内存池,并强制 LuaJIT 使用系统内存分配器(默认情况下,LuaJIT 使用自己的内存分配器)。此外,我们还应该启用各种 OpenResty 核心组件(如 ngx_lua
和 LuaJIT)中的内部断言。
为了简化 Valgrind 使用的特殊构建设置,OpenResty 为各种常见的 Linux 发行版提供了 openresty-valgrind
预构建的 Linux 包。
- https://openresty.org.cn/en/linux-packages.html
- https://openresty.org.cn/en/deb-packages.html#openresty-valgrind
- https://openresty.org.cn/en/rpm-packages.html#openresty-valgrind
如果您的 Linux 系统尚未在预构建的软件包存储库中得到支持,则可以按照 openresty-valgrind
的 RPM 规范文件 中的步骤构建您自己的 openresty-valgrind
。
除此之外,请记住在 nginx.conf
的顶层范围中配置以下几行,以确保 nginx 在由 valgrind 运行时作为单个非守护进程运行。
daemon off;
master_process off;
worker_processes 1;
强烈不建议在 Mac OS X 或 macOS 等非 Linux 系统上使用 Valgrind,因为 Valgrind 在这些系统上的支持非常有限,甚至有错误。
OpenResty 的 Test::Nginx
测试脚手架提供了对使用 Valgrind 运行测试的内置支持,称为“Valgrind 测试模式”。您可以在“OpenResty 编程”书籍的在线版中找到包含示例的详细文档。
https://openresty.gitbooks.io/programming-openresty/content/testing/test-modes.html#_valgrind_mode
Valgrind 的一个局限性是:当您的 OpenResty 应用程序需要大量的真实流量才能重现问题,或者您必须启用特殊 nginx 子进程(如工作进程和缓存管理器进程)才能重现问题时,您可以考虑使用 clang 或 gcc 的 AddressSanitizer (ASAN) 工具重新构建您的 OpenResty,该工具的性能也更高。
例如,您可以使用 ASAN 构建 OpenResty,方法如下:
export ASAN_OPTIONS=detect_leaks=0
./configure --with-cc="gcc -fsanitize=address" \
--with-cc-opt="-O1 -fno-omit-frame-pointer" --with-debug -j9 \
--prefix=/usr/local/openresty-asan --with-luajit-xcflags="-DLUAJIT_USE_VALGRIND" \
--with-no-pool-patch
make -j9
sudo make install
确保在运行此 openresty(安装在 /usr/local/openresty-asan/
下)时还设置了环境变量 ASAN_OPTIONS=detect_leaks=0
,否则您会看到很多关于内存泄漏的误报。
我们将在不久的将来在我们的官方 OpenResty Linux 软件包存储库中提供 openresty-asan
软件包,以便简化此操作。
但 ASAN 也有一个局限性:它无法检查在即时 (JIT) 编译代码(如 PCRE JIT 和 LuaJIT 的 JIT 编译器生成的机器代码)或任何手工编写的汇编代码(如 OpenSSL 或 LuaJIT 的解释器)中发生的内存问题。