1. 为什么选择源码编译安装 OpenResty很多人第一次接触 OpenResty下意识就去翻系统自带的包管理器apt install openresty或者yum install openresty一条命令搞定省事是省事但我在实际项目里踩过好几次坑之后现在基本只推荐源码编译这一条路。原因不复杂发行版仓库里的 OpenResty 版本往往滞后半年甚至更久而 OpenResty 的迭代节奏跟 LuaJIT、ngx_lua 模块、各种 lua-resty 库的兼容性绑定很紧版本差一点某些新特性就用不了某些已知问题也修不掉。源码编译的另一个好处是可控。你可以精确指定编译哪些模块、链接哪个版本的 OpenSSL、开启哪些调试符号。这在生产环境做性能调优或者排查疑难问题时价值非常大。举个例子默认包安装的 OpenResty 通常不带 debug 符号一旦遇到 Lua 层面的诡异崩溃gdb 堆栈全是问号根本没法看。源码编译时加上--with-debug问题定位效率完全不是一个量级。当然源码编译也不是没有代价。依赖库要自己装编译参数要自己调升级时还得重新走一遍流程。但这些东西一旦跑通一次后面就是复制粘贴的事。我下面会把整个流程拆开讲清楚包括每一步为什么这么做、参数怎么选、遇到报错怎么排查尽量让你一次跑通不用反复试错。这篇文章适合几类人一是刚接触 OpenResty、想在自己机器上搭一套完整开发环境的新手二是在生产环境需要精确控制版本和模块的老手三是之前用包管理器装过但遇到各种奇怪问题、想换源码编译路线的同学。不管你基础如何跟着走一遍应该都能在自己的 Linux 机器上跑起来一个可用的 OpenResty。2. 安装前的环境准备与依赖梳理2.1 系统环境确认与基础工具安装动手之前先确认几件事。第一你的 Linux 发行版和版本。我用的是某主流服务器发行版的最新稳定版内核版本在 5.x 以上。不同发行版的包管理命令不一样但核心依赖大同小异。第二确认你有 root 权限或者 sudo 权限因为安装依赖和写入/usr/local目录都需要提权。第三确认磁盘空间OpenResty 源码加上编译产物大概需要 500MB 到 1GB留足空间避免编译中途失败。基础工具这块gcc、make、perl是必须的。perl容易被忽略但 OpenResty 编译过程中会用到它来生成一些配置和脚本。另外wget或curl用来下载源码包tar用来解压。这些工具大部分系统自带但最小化安装的镜像可能没有建议先装一遍。# 以某主流发行版为例先更新包索引 sudo apt update # 安装编译基础工具链 sudo apt install -y gcc make perl wget tar # 确认版本 gcc --version make --version perl --version这里有个细节gcc版本不要太老也不要太新。太老比如 4.x可能不支持某些 C99 特性太新比如 13.x偶尔会触发一些警告被当成错误。我实测下来gcc 9 到 12 这个区间最稳。如果你系统自带的 gcc 版本不在这个范围可以考虑装一个特定版本的 gcc 并用update-alternatives切换。2.2 核心依赖库的选择与安装OpenResty 依赖几个关键库PCRE、zlib、OpenSSL。这三个库的版本选择直接影响到后续功能。PCRE 用于正则表达式支持OpenResty 的location匹配、rewrite规则都依赖它。建议用 PCRE2性能比 PCRE1 好而且新版本 OpenResty 已经默认支持。zlib 用于 gzip 压缩这个基本没得选用系统自带的就行。OpenSSL 是最需要留意的因为它涉及 TLS 版本、加密套件、SNI 等一堆东西。系统自带的 OpenSSL 版本可能偏旧我建议单独编译一个较新的稳定版编译 OpenResty 时通过--with-openssl指定路径。# 安装 PCRE2 开发库 sudo apt install -y libpcre2-dev # 安装 zlib 开发库 sudo apt install -y zlib1g-dev # 安装 OpenSSL 开发库如果不想单独编译 sudo apt install -y libssl-dev如果你决定单独编译 OpenSSL流程也不复杂下载源码、./config、make、make install装到一个独立目录比如/opt/openssl。这样做的好处是系统自带的 OpenSSL 不受影响其他软件继续用系统的OpenResty 用你指定的版本。坏处是后续升级 OpenSSL 需要重新编译 OpenResty因为它是静态链接进去的。提示如果你只是本地开发测试用系统自带的libssl-dev就够了没必要折腾单独编译。但如果是生产环境尤其是需要支持较新 TLS 版本或者特定加密套件的场景单独编译 OpenSSL 更稳妥。2.3 用户与目录规划OpenResty 默认安装到/usr/local/openresty这个路径没问题但运行时的用户和目录需要提前规划。默认情况下OpenResty 的 worker 进程以nobody用户运行这在某些系统上可能权限不够。我习惯创建一个专用用户www-data或者openresty把日志目录、缓存目录的权限给它。# 创建专用用户组和用户 sudo groupadd -r openresty sudo useradd -r -g openresty -s /sbin/nologin openresty # 创建日志和缓存目录 sudo mkdir -p /var/log/openresty sudo mkdir -p /var/cache/openresty sudo chown -R openresty:openresty /var/log/openresty sudo chown -R openresty:openresty /var/cache/openresty目录规划这块我建议把配置、日志、缓存、临时文件分开存放。配置放/usr/local/openresty/nginx/conf日志放/var/log/openresty缓存放/var/cache/openresty临时文件放/var/tmp/openresty。这样后续做日志轮转、磁盘监控、权限管理都清晰。别把所有东西都堆在默认目录里时间一长自己都找不到。3. 源码编译 OpenResty 的完整实操3.1 下载与解压源码包OpenResty 的官方发布页提供两种包openresty-x.x.x.x.tar.gz和openresty-x.x.x.x-win32.zip。Linux 下用前者。下载地址在官方站点版本号选最新的稳定版。我写这篇文章时最新稳定版是 1.25.x 系列但具体版本号你以官方页面为准。# 下载源码包版本号请替换为最新稳定版 cd /usr/local/src sudo wget https://openresty.org/download/openresty-1.25.3.1.tar.gz # 校验文件完整性可选但推荐 sudo wget https://openresty.org/download/openresty-1.25.3.1.tar.gz.asc gpg --verify openresty-1.25.3.1.tar.gz.asc # 解压 sudo tar -zxvf openresty-1.25.3.1.tar.gz cd openresty-1.25.3.1校验这一步很多人跳过但我建议做。源码包在下载过程中可能损坏或者被中间人篡改。GPG 校验能确保你拿到的包是官方发布的原始版本。如果校验失败重新下载别硬着头皮编译否则后面报一堆莫名其妙的错排查起来更浪费时间。解压之后你会看到目录结构bundle目录里是 OpenResty 自带的一堆第三方模块比如lua-resty-core、lua-resty-lrucache、ngx_lua等。configure脚本在根目录。先别急着编译下一步是配置参数。3.2 configure 参数详解与选择逻辑./configure是编译过程中最关键的一步参数选错了后面要么功能缺失要么性能不达标。我先把常用参数列出来再逐个解释。./configure \ --prefix/usr/local/openresty \ --with-pcre-jit \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-http_auth_request_module \ --with-threads \ --with-file-aio \ --with-http_flv_module \ --with-http_mp4_module \ --with-ld-opt-Wl,-rpath,/usr/local/openresty/luajit/lib \ --with-cc-opt-O2 -g--prefix指定安装路径默认就是/usr/local/openresty写不写都行但显式写出来更清晰。--with-pcre-jit开启 PCRE 的 JIT 编译正则匹配性能提升明显尤其是复杂正则场景。--with-http_ssl_module和--with-http_v2_module是 HTTPS 和 HTTP/2 支持现代 Web 服务基本必开。--with-http_realip_module用于获取客户端真实 IP如果你前面有反向代理或者 CDN这个模块必须开否则日志里全是代理的 IP。--with-http_stub_status_module提供基础的状态监控接口配合lua-resty-*库可以做更细粒度的监控。--with-http_gzip_static_module支持预压缩文件的直接返回省 CPU。--with-threads开启线程池支持某些阻塞操作比如文件 IO可以放到线程池里执行避免阻塞事件循环。--with-file-aio开启异步文件 IO对静态文件服务有帮助。--with-http_flv_module和--with-http_mp4_module是流媒体支持如果你不做视频相关业务可以去掉。--with-ld-opt和--with-cc-opt是链接和编译选项。-Wl,-rpath指定运行时库搜索路径避免装完之后找不到 LuaJIT 的库。-O2是优化级别-g保留调试符号。生产环境如果追求极致性能可以用-O3但编译时间会变长而且某些情况下-O3反而会触发编译器 bug-O2是最稳的选择。注意如果你单独编译了 OpenSSL需要加--with-openssl/path/to/openssl/source注意这里指向的是源码目录不是安装目录。OpenResty 编译时会自己编译 OpenSSL 并静态链接进去。3.3 编译与安装过程记录配置完成后make开始编译。这个过程比较耗时取决于机器性能一般 5 到 15 分钟。我习惯用make -j$(nproc)并行编译充分利用多核 CPU。# 并行编译nproc 返回 CPU 核心数 make -j$(nproc) # 编译完成后安装 sudo make install编译过程中如果报错常见的有几类一是缺少依赖库比如pcre.h找不到说明libpcre2-dev没装或者路径不对二是 gcc 版本不兼容报一些语法错误或者警告被当成错误三是 OpenSSL 版本冲突系统里存在多个 OpenSSL 导致链接混乱。遇到报错先看错误信息的第一行通常那里就指明了原因。安装完成后检查一下关键文件是否存在# 检查 nginx 二进制 /usr/local/openresty/nginx/sbin/nginx -V # 检查 luajit /usr/local/openresty/luajit/bin/luajit -v # 检查 resty 命令行工具 /usr/local/openresty/bin/resty -e print(hello openresty)nginx -V会输出编译时的所有参数你可以核对一下之前配置的参数是否都生效了。resty是 OpenResty 提供的命令行工具可以直接运行 Lua 代码测试 LuaJIT 是否正常工作。如果这三条命令都正常输出说明安装基本成功。3.4 环境变量与系统集成装完之后为了方便使用把 OpenResty 的二进制目录加到PATH里。编辑/etc/profile.d/openresty.shexport PATH/usr/local/openresty/bin:/usr/local/openresty/nginx/sbin:$PATH export LUA_PATH/usr/local/openresty/lualib/?.lua;; export LUA_CPATH/usr/local/openresty/lualib/?.so;;LUA_PATH和LUA_CPATH是给 LuaJIT 用的指定 Lua 模块的搜索路径。OpenResty 自带的lua-resty-*库都在/usr/local/openresty/lualib下面设置好这两个变量你在写 Lua 代码时require才能找到这些库。然后source /etc/profile.d/openresty.sh让配置生效。接着配置 systemd 服务方便开机自启和管理。# /etc/systemd/system/openresty.service [Unit] DescriptionOpenResty Afternetwork.target [Service] Typeforking PIDFile/usr/local/openresty/nginx/logs/nginx.pid ExecStartPre/usr/local/openresty/nginx/sbin/nginx -t ExecStart/usr/local/openresty/nginx/sbin/nginx ExecReload/usr/local/openresty/nginx/sbin/nginx -s reload ExecStop/usr/local/openresty/nginx/sbin/nginx -s quit PrivateTmptrue [Install] WantedBymulti-user.targetExecStartPre先做配置检查配置有问题直接启动失败避免带病运行。ExecReload用reload而不是restart实现平滑重载不中断现有连接。ExecStop用quit而不是stop让 worker 进程处理完当前请求再退出。sudo systemctl daemon-reload sudo systemctl enable openresty sudo systemctl start openresty sudo systemctl status openresty到这里一个完整的 OpenResty 环境就搭好了。你可以写一个最简单的测试配置验证一下 Lua 代码是否能正常执行。4. 安装后的验证与基础配置4.1 最小化配置验证安装完成后别急着上生产配置先用一个最小化的nginx.conf验证核心功能。我一般会写一个包含 Lua 处理的测试配置确认content_by_lua_block能正常工作。# /usr/local/openresty/nginx/conf/nginx.conf 的最小化版本 worker_processes 1; error_log /var/log/openresty/error.log info; pid /usr/local/openresty/nginx/logs/nginx.pid; events { worker_connections 1024; } http { access_log /var/log/openresty/access.log; server { listen 8080; server_name localhost; location / { default_type text/plain; content_by_lua_block { ngx.say(OpenResty is running, version: , ngx.config.nginx_version) ngx.say(LuaJIT version: , jit.version) } } location /status { stub_status on; access_log off; } } }这个配置做了几件事监听 8080 端口根路径返回 OpenResty 和 LuaJIT 版本信息/status路径返回 Nginx 的基础状态数据。content_by_lua_block是 OpenResty 最核心的指令之一它让 Lua 代码直接处理请求并生成响应。配置写好后先测试语法sudo /usr/local/openresty/nginx/sbin/nginx -t如果输出syntax is ok和test is successful说明配置没问题。然后重载或者启动sudo systemctl reload openresty # 或者如果没配 systemd sudo /usr/local/openresty/nginx/sbin/nginx -s reload用curl测试curl http://127.0.0.1:8080/ curl http://127.0.0.1:8080/status第一个请求应该返回类似OpenResty is running, version: 1025003和LuaJIT version: LuaJIT 2.1.0-beta3的内容。第二个请求返回Active connections: 1之类的状态信息。如果都能正常返回说明安装和基础配置都成功了。4.2 常见安装报错与排查思路安装过程中最容易遇到的几个问题我整理成表格方便你对照排查。报错信息可能原因解决方法./configure: error: SSL modules require the OpenSSL library缺少 OpenSSL 开发库安装libssl-dev或指定--with-openssl路径checking for PCRE library ... not found缺少 PCRE 开发库安装libpcre2-dev确认头文件路径error: lua_State undeclaredLuaJIT 头文件路径不对检查--with-luajit参数确认 bundle 目录完整nginx: error while loading shared libraries: libluajit-5.1.so.2运行时找不到 LuaJIT 库加--with-ld-opt-Wl,-rpath,/usr/local/openresty/luajit/lib重新编译make: *** No rule to make target build源码目录不完整或解压出错重新下载源码包校验完整性后重新解压perl: command not found缺少 perl安装 perl排查思路很简单先看错误信息的第一行定位是哪个阶段出的问题。configure阶段报错通常是依赖缺失make阶段报错通常是代码或编译器问题make install阶段报错通常是权限问题。按这个顺序排查大部分问题都能快速解决。提示如果你在make阶段遇到一堆警告被当成错误可以在--with-cc-opt里加-Wno-error让编译器不把警告当错误。但这只是权宜之计最好还是搞清楚警告的原因。4.3 性能相关的编译参数调优如果你对性能有要求编译参数还可以进一步调优。几个关键点第一--with-pcre-jit一定要开正则匹配在 Web 服务里非常频繁JIT 带来的提升很可观。第二--with-cc-opt里的优化级别-O2是平衡点-O3在某些场景下能再提升几个百分点但编译时间翻倍而且可能触发编译器优化 bug。第三如果 CPU 支持特定指令集可以加-marchnative让编译器针对当前 CPU 生成最优代码。但这个参数的可移植性差编译出来的二进制换一台 CPU 可能就跑不了生产环境慎用。# 针对当前 CPU 优化的编译参数示例 --with-cc-opt-O2 -g -marchnative -mtunenative还有一个容易被忽略的点LuaJIT 的编译参数。OpenResty 自带的 LuaJIT 默认配置已经比较优了但如果你有特殊需求可以通过--with-luajit-xcflags传递额外参数。比如开启-DLUAJIT_ENABLE_LUA52COMPAT来兼容 Lua 5.2 的部分语法。这个参数会影响 Lua 代码的写法建议先确认你的代码是否需要。5. 实操心得与避坑指南5.1 版本选择与升级策略OpenResty 的版本号跟 Nginx 版本号是绑定的比如 1.25.3.1 对应 Nginx 1.25.3。选版本时优先选官方标记为 stable 的版本别追最新的 beta 版。生产环境尤其如此beta 版可能有未发现的 bug出了问题官方支持也有限。升级策略上我建议小版本升级直接覆盖安装大版本升级先在新机器上验证。覆盖安装时配置文件通常兼容但要注意lua-resty-*库的 API 变化。OpenResty 的升级文档里会列出不兼容的变更升级前务必读一遍。另外升级前备份好配置和 Lua 代码万一出问题可以快速回滚。# 备份当前配置 sudo tar -czf /root/openresty-conf-backup-$(date %Y%m%d).tar.gz /usr/local/openresty/nginx/conf # 升级后如果出问题回滚配置 sudo tar -xzf /root/openresty-conf-backup-20250101.tar.gz -C /5.2 日志与监控的初始配置装完 OpenResty 之后日志和监控要尽早配好。默认的error_log级别是error我建议开发环境用info生产环境用warn或error。info级别日志量大但排查问题时信息全。生产环境日志量太大会拖慢性能而且占磁盘。访问日志方面OpenResty 支持自定义日志格式可以把请求耗时、上游响应时间、Lua 处理时间都记下来。这些数据对性能分析非常有用。log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for rt$request_time uct$upstream_connect_time uht$upstream_header_time urt$upstream_response_time; access_log /var/log/openresty/access.log main;$request_time是 Nginx 处理请求的总时间$upstream_*是上游服务的耗时。如果$request_time远大于$upstream_response_time说明瓶颈在 Nginx 本身或者 Lua 代码如果两者接近说明瓶颈在上游服务。这个判断逻辑在排查性能问题时非常实用。监控方面stub_status模块提供基础指标但更细粒度的监控建议用lua-resty-prometheus之类的库把指标暴露给监控系统。这块内容展开又是一大篇这里先不深入你只需要知道装完之后尽早把监控接上别等出问题了才想起来没数据。5.3 常见配置陷阱与规避方法第一个陷阱content_by_lua_block和content_by_lua_file混用。同一个location里只能有一个内容处理指令混用会导致配置报错。我见过有人同时写content_by_lua_block和proxy_pass结果 Nginx 启动直接失败。记住Lua 内容处理器和代理、静态文件服务是互斥的。第二个陷阱lua_code_cache在生产环境必须开启。开发时为了方便很多人会设lua_code_cache off这样每次请求都重新加载 Lua 代码改完立即生效。但生产环境必须设为on否则性能会下降几十倍。我实测过一个简单接口lua_code_cache off时 QPS 只有几百on之后直接上万。第三个陷阱共享内存字典lua_shared_dict的大小设置。设太小会导致缓存频繁淘汰设太大会浪费内存。一般根据缓存数据量和过期策略来估算。比如你缓存 10 万个 key每个 key 平均 1KB那至少需要 100MB再加上一些余量设 128MB 比较合适。lua_shared_dict my_cache 128m;第四个陷阱init_by_lua_block里做耗时操作。这个指令在 Nginx 启动时执行如果里面做了网络请求或者大量计算会导致启动变慢甚至超时。init_by_lua_block里只做轻量的初始化比如加载配置、预编译正则耗时的操作放到init_worker_by_lua_block或者定时器里。5.4 从包管理器迁移到源码编译的注意事项如果你之前用包管理器装的 OpenResty现在想换源码编译有几个地方要注意。第一先卸载包管理器版本避免二进制冲突。apt remove openresty或者yum remove openresty然后确认/usr/local/openresty目录是干净的。第二配置文件要迁移过来但注意包管理器版本的配置路径可能跟源码编译不一样通常是/etc/nginx和/usr/local/openresty/nginx/conf的区别。第三systemd 服务文件要替换包管理器版本的服务文件指向的二进制路径不同。迁移过程中最容易出问题的是 Lua 库的路径。包管理器版本可能把lua-resty-*库装在/usr/share/lua/5.1下面而源码编译版本在/usr/local/openresty/lualib。迁移后要确认LUA_PATH和LUA_CPATH指向正确否则require会报模块找不到。提示迁移前先在测试环境走一遍完整流程确认所有功能正常后再动生产环境。生产环境迁移最好选在低峰期并且准备好回滚方案。6. 写在最后的一些个人体会源码编译 OpenResty 这件事第一次做会觉得步骤多、参数杂但跑通一次之后你会发现整个过程其实很线性装依赖、配参数、编译、安装、验证。真正花时间的不是操作本身而是遇到报错时的排查。我建议你第一次编译时把每一步的输出都重定向到日志文件比如./configure ... 21 | tee configure.log这样出问题时可以回溯。另外别怕折腾。我见过很多人因为怕编译出错一直用包管理器版本结果遇到版本兼容问题时束手无策。源码编译给了你完全的控制权这个控制权在关键时刻能救命。比如某个安全漏洞需要紧急升级 OpenSSL包管理器版本可能要等官方更新而源码编译版本你可以自己控制升级节奏。最后分享一个小技巧编译完成后把整个/usr/local/openresty目录打包备份。下次在新机器上部署时如果系统环境一致直接解压就能用省去编译时间。这个方式在批量部署时特别高效我管它叫“绿色版 OpenResty”。当然前提是目标机器的 glibc 版本兼容否则还是得重新编译。