OpenResty > 平滑升级:1.25.x → 1.27.x

文章目录

  • [OpenResty 平滑升级指南:1.25.3.2 → 1.27.1.2(编译安装方式)](#OpenResty 平滑升级指南:1.25.3.2 → 1.27.1.2(编译安装方式))
    • 一、升级概述
      • [1.1 当前环境](#1.1 当前环境)
      • [1.2 目标版本](#1.2 目标版本)
      • [1.3 主要变更](#1.3 主要变更)
        • 核心升级
        • [lua-nginx-module 增强](#lua-nginx-module 增强)
        • [SSL/TLS 改进](#SSL/TLS 改进)
        • 安全修复
        • [LuaJIT 修复](#LuaJIT 修复)
    • 二、升级前准备
      • [2.1 检查系统依赖](#2.1 检查系统依赖)
      • [2.2 备份当前环境](#2.2 备份当前环境)
      • [2.3 记录当前状态](#2.3 记录当前状态)
      • [2.4 兼容性检查](#2.4 兼容性检查)
    • [三、编译安装 OpenResty 1.27](#三、编译安装 OpenResty 1.27)
      • [3.1 下载源码](#3.1 下载源码)
      • [3.2 配置编译参数](#3.2 配置编译参数)
      • [3.3 编译和安装](#3.3 编译和安装)
      • [3.4 验证新版本](#3.4 验证新版本)
    • 四、迁移配置文件
      • [4.1 复制配置到新版本](#4.1 复制配置到新版本)
      • [4.2 调整配置文件路径](#4.2 调整配置文件路径)
      • [4.3 测试新版本配置](#4.3 测试新版本配置)
    • 五、平滑升级步骤(零停机)
      • [方式一:使用 Nginx 信号进行平滑升级(推荐)⭐](#方式一:使用 Nginx 信号进行平滑升级(推荐)⭐)
        • [5.1 理解平滑升级原理](#5.1 理解平滑升级原理)
        • [5.2 执行平滑升级](#5.2 执行平滑升级)
          • [步骤 1:获取旧 master 进程 PID](#步骤 1:获取旧 master 进程 PID)
          • [步骤 2:向旧 master 发送 USR2 信号](#步骤 2:向旧 master 发送 USR2 信号)
          • [步骤 2(替代方案):手动启动新版本](#步骤 2(替代方案):手动启动新版本)
          • [步骤 3:优雅关闭旧版本 worker 进程](#步骤 3:优雅关闭旧版本 worker 进程)
          • [步骤 4:测试新版本](#步骤 4:测试新版本)
          • [步骤 5:完全关闭旧版本或保留回滚选项](#步骤 5:完全关闭旧版本或保留回滚选项)
        • [5.3 快速回滚(如果需要)](#5.3 快速回滚(如果需要))
      • 方式二:替换二进制文件升级(不推荐)
      • 方式三:停机升级(适用于可以容忍短暂停机的场景)
    • 六、升级验证
      • [6.1 基础功能测试](#6.1 基础功能测试)
      • [6.2 配置验证](#6.2 配置验证)
      • [6.3 Lua 功能测试](#6.3 Lua 功能测试)
      • [6.4 日志检查](#6.4 日志检查)
      • [6.5 性能对比测试](#6.5 性能对比测试)
      • [6.6 业务功能测试](#6.6 业务功能测试)
    • 七、后续清理
      • [7.1 环境清理(确认新版本稳定后)](#7.1 环境清理(确认新版本稳定后))
      • [7.2 创建启动脚本(可选)](#7.2 创建启动脚本(可选))
      • [7.3 配置开机自启(macOS LaunchDaemon)](#7.3 配置开机自启(macOS LaunchDaemon))
    • 八、常见问题与解决方案
      • [8.1 编译失败:找不到依赖](#8.1 编译失败:找不到依赖)
      • [8.2 启动失败:端口被占用](#8.2 启动失败:端口被占用)
      • [8.3 配置测试失败](#8.3 配置测试失败)
      • [8.4 Lua 脚本报错:找不到模块](#8.4 Lua 脚本报错:找不到模块)
      • [8.5 权限问题](#8.5 权限问题)
      • [8.6 信号升级失败](#8.6 信号升级失败)
    • 九、回滚方案
      • [9.1 紧急回滚(新版本有严重问题)](#9.1 紧急回滚(新版本有严重问题))
      • [9.2 优雅回滚(新版本有小问题,但可以等待)](#9.2 优雅回滚(新版本有小问题,但可以等待))
      • [9.3 恢复配置文件](#9.3 恢复配置文件)
    • 十、升级检查清单
    • 十一、附录
      • [A. 目录结构对比](#A. 目录结构对比)
      • [B. 常用命令速查](#B. 常用命令速查)
      • [C. 编译参数对比](#C. 编译参数对比)
      • [D. 参考资料](#D. 参考资料)
      • [E. 故障排查清单](#E. 故障排查清单)
    • 十二、升级时间规划建议
      • [12.1 小型项目(个人或开发环境)](#12.1 小型项目(个人或开发环境))
      • [12.2 中型项目(生产环境,有备份节点)](#12.2 中型项目(生产环境,有备份节点))
      • [12.3 大型项目(核心生产环境)](#12.3 大型项目(核心生产环境))

OpenResty 平滑升级指南:1.25.3.2 → 1.27.1.2(编译安装方式)

一、升级概述

1.1 当前环境

  • 当前版本:OpenResty 1.25.3.2 (基于 nginx 1.25.3)
  • 安装路径/usr/local/openresty-1.25/
  • 配置文件/usr/local/openresty-1.25/nginx/conf/nginx.conf
  • 运行状态:进程已运行,主进程 PID 43158
  • 当前编译参数
bash 复制代码
--prefix=/usr/local/openresty-1.25/nginx
--with-cc-opt='-O2 -I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/pcre/include'
--with-ld-opt='-Wl,-rpath,/usr/local/openresty-1.25/luajit/lib -L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/pcre/lib'
--with-pcre-jit
--with-http_ssl_module
--with-http_v2_module
--with-http_realip_module
--with-http_stub_status_module
--with-stream
--with-stream_ssl_module
--with-stream_ssl_preread_module
--without-pcre2

1.2 目标版本

1.3 主要变更

OpenResty 1.27 相比 1.25 的重要更新:

核心升级
  • 升级到最新的 nginx 1.27.1 主线版本
  • 新增两个官方模块:http_v3_module(HTTP/3)和 http_slice_module
lua-nginx-module 增强
  • 支持 ngx.location.capturengx.location.capture_multi 的 headers 选项
  • balancer_by_lua* 中实现 keepalive 连接池
  • ssl_certificate_by_luassl_client_hello_by_lua 阶段启用 ngx.var
  • 移除 ngx.location 子请求 API 中的 http2 硬编码限制
SSL/TLS 改进
  • 新增解析 DER 格式证书/密钥的函数
  • ssl.verify_client() 添加 ssl_trusted_certificate 参数
安全修复
  • 修复哈希计算优化导致的性能退化问题 (CVE-2024-39702)
LuaJIT 修复
  • 修复 BC_VARG 录制问题
  • 修复 __concat 元方法抛出 OOM 时的状态恢复

二、升级前准备

2.1 检查系统依赖

bash 复制代码
# macOS 需要的依赖(通过 Homebrew 安装)
brew install pcre openssl@3 perl

# 验证依赖
brew list pcre openssl@3 perl

2.2 备份当前环境

bash 复制代码
# 1. 备份配置文件(带时间戳)
sudo cp -r /usr/local/openresty-1.25/nginx/conf \
  /usr/local/openresty-1.25/nginx/conf.backup_$(date +%Y%m%d_%H%M%S)

# 2. 备份整个 OpenResty 目录(可选但推荐)
sudo tar -czf ~/openresty-1.25-backup-$(date +%Y%m%d_%H%M%S).tar.gz \
  /usr/local/openresty-1.25/

# 3. 导出当前编译参数
/usr/local/openresty-1.25/nginx/sbin/nginx -V 2>&1 | \
  tee ~/openresty-1.25-build-info.txt

2.3 记录当前状态

bash 复制代码
# 1. 记录运行的进程
ps aux | grep nginx | grep -v grep > ~/openresty-1.25-processes.txt

# 2. 检查当前监听端口
sudo lsof -i -P | grep nginx > ~/openresty-1.25-ports.txt

# 3. 测试配置文件有效性
sudo /usr/local/openresty-1.25/nginx/sbin/nginx -t

# 4. 记录当前访问情况(可选)
curl -I http://localhost

2.4 兼容性检查

检查你的 Lua 代码和配置文件,特别注意:

  1. ✅ 检查是否使用了 ngx.location.capture* 的 headers 选项(新版本支持)
  2. ✅ 检查 balancer_by_lua* 中的连接处理(新版本支持 keepalive)
  3. ✅ 检查是否在 SSL 相关阶段使用 ngx.var(新版本支持)
  4. ⚠️ 检查是否有硬编码的路径指向旧版本目录
  5. ⚠️ 检查第三方 Lua 模块是否兼容新版本

三、编译安装 OpenResty 1.27

3.1 下载源码

bash 复制代码
# 1. 创建临时编译目录
mkdir -p ~/openresty-build
cd ~/openresty-build

# 2. 下载 OpenResty 1.27.1.2 源码
curl -LO https://openresty.org/download/openresty-1.27.1.2.tar.gz

# 3. 验证下载(可选)
# 从官网获取 SHA256 校验和进行验证
# curl -LO https://openresty.org/download/openresty-1.27.1.2.tar.gz.asc

# 4. 解压源码
tar -xzf openresty-1.27.1.2.tar.gz
cd openresty-1.27.1.2

# 5. 查看目录结构
ls -la

3.2 配置编译参数

根据你的 1.25 版本的编译参数,配置 1.27 版本。

重要说明

  • 使用 --prefix=/usr/local/openresty-1.27 安装到独立目录
  • 这样可以保留旧版本,便于快速回滚
  • 保持与旧版本相同的编译选项,确保功能一致
bash 复制代码
# 配置编译参数(与旧版本保持一致,只修改 prefix 和 rpath)
./configure \
  --prefix=/usr/local/openresty-1.27 \
  --with-cc-opt="-O2 -I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/pcre/include" \
  --with-ld-opt="-Wl,-rpath,/usr/local/openresty-1.27/luajit/lib -L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/pcre/lib" \
  --with-pcre-jit \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_realip_module \
  --with-http_stub_status_module \
  --with-stream \
  --with-stream_ssl_module \
  --with-stream_ssl_preread_module \
  --without-pcre2

# 查看配置结果
# ./configure 完成后会显示配置摘要

可选的新特性模块(如果需要):

bash 复制代码
# 如果想启用 HTTP/3 支持(需要额外依赖)
# --with-http_v3_module

# 如果想启用 slice 模块
# --with-http_slice_module

3.3 编译和安装

bash 复制代码
# 1. 编译(使用多核加速,假设 8 核 CPU)
make -j8

# 2. 等待编译完成(约 3-10 分钟,取决于机器性能)
# 如果编译出错,查看错误信息并解决依赖问题

# 3. 安装到 /usr/local/openresty-1.27/
sudo make install

# 4. 验证安装
ls -la /usr/local/openresty-1.27/

3.4 验证新版本

bash 复制代码
# 1. 检查新版本
/usr/local/openresty-1.27/nginx/sbin/nginx -v

# 2. 查看详细编译信息
/usr/local/openresty-1.27/nginx/sbin/nginx -V

# 3. 验证 LuaJIT
/usr/local/openresty-1.27/luajit/bin/luajit -v

# 4. 检查目录结构
tree -L 2 /usr/local/openresty-1.27/ # 如果安装了 tree
# 或
ls -la /usr/local/openresty-1.27/nginx/

预期输出:

复制代码
nginx version: openresty/1.27.1.2
built by clang ...
built with OpenSSL 3.x.x ...
TLS SNI support enabled

四、迁移配置文件

4.1 复制配置到新版本

bash 复制代码
# 1. 备份新版本的默认配置(可选)
sudo cp -r /usr/local/openresty-1.27/nginx/conf \
  /usr/local/openresty-1.27/nginx/conf.default

# 2. 复制旧版本的配置文件到新版本
sudo cp -r /usr/local/openresty-1.25/nginx/conf/* \
  /usr/local/openresty-1.27/nginx/conf/

# 3. 如果有自定义的 Lua 脚本或模块目录,也需要复制
# 例如:
# sudo cp -r /usr/local/openresty-1.25/lualib/* \
#   /usr/local/openresty-1.27/lualib/

4.2 调整配置文件路径

需要检查和更新配置文件中的绝对路径引用:

bash 复制代码
# 1. 检查配置文件中是否有硬编码的旧路径
grep -r "/usr/local/openresty-1.25" /usr/local/openresty-1.27/nginx/conf/

# 2. 如果有,需要手动编辑替换
# 例如编辑主配置文件
sudo nano /usr/local/openresty-1.27/nginx/conf/nginx.conf
# 或使用 vim
sudo vim /usr/local/openresty-1.27/nginx/conf/nginx.conf

需要检查的配置项

nginx 复制代码
# 1. 错误日志和访问日志路径(通常是相对路径,无需修改)
error_log  logs/error.log;
access_log logs/access.log;

# 2. Lua 包路径(如果有硬编码的绝对路径)
lua_package_path "/usr/local/openresty-1.27/lualib/?.lua;;";
lua_package_cpath "/usr/local/openresty-1.27/lualib/?.so;;";

# 3. 包含的配置文件(如果使用绝对路径)
include /usr/local/openresty-1.27/nginx/conf/vhost/*.conf;

# 4. SSL 证书路径(通常使用绝对路径)
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;

# 5. 临时文件路径(通常是相对路径)
client_body_temp_path temp/client_body_temp;
proxy_temp_path temp/proxy_temp;

4.3 测试新版本配置

bash 复制代码
# 1. 测试配置文件语法
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -t

# 2. 查看详细的配置错误信息
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -t -c /usr/local/openresty-1.27/nginx/conf/nginx.conf

# 3. 如果测试失败,查看错误日志
tail -f /usr/local/openresty-1.27/nginx/logs/error.log

常见配置错误

  • 路径不存在
  • 权限不足
  • 模块未编译
  • 语法错误

五、平滑升级步骤(零停机)

方式一:使用 Nginx 信号进行平滑升级(推荐)⭐

这是最佳方式,可以实现完全的零停机升级。

5.1 理解平滑升级原理

Nginx 支持在不停止服务的情况下升级二进制文件:

  1. 旧 master 进程收到 USR2 信号后,会启动新的二进制文件作为新 master
  2. 新 master 会启动新的 worker 进程
  3. 旧 master 收到 WINCH 信号后,会优雅关闭旧 worker 进程
  4. 新 worker 接管所有新连接
  5. 旧 worker 处理完现有连接后退出
  6. 如果新版本有问题,可以回滚到旧版本
5.2 执行平滑升级
步骤 1:获取旧 master 进程 PID
bash 复制代码
# 方法 1:从进程列表获取
ps aux | grep nginx | grep master

# 方法 2:从 PID 文件读取(如果存在)
cat /usr/local/openresty-1.25/nginx/logs/nginx.pid

# 假设旧 master PID 是 43158
OLD_PID=43158
echo "旧版本 Master PID: $OLD_PID"
步骤 2:向旧 master 发送 USR2 信号
bash 复制代码
# 发送 USR2 信号,告诉旧 master 启动新的二进制文件
sudo kill -USR2 $OLD_PID

# 等待 2-3 秒,让新进程启动
sleep 3

# 查看进程,应该看到新旧两组进程
ps aux | grep nginx

注意USR2 信号会让旧 master:

  1. 重命名 PID 文件:nginx.pidnginx.pid.oldbin
  2. 使用新的二进制文件/usr/local/openresty-1.27/nginx/sbin/nginx)启动新 master

但是,这里有个关键问题 :旧 master 会尝试执行 当前路径 下的二进制文件,而不是新路径的。

步骤 2(替代方案):手动启动新版本

推荐方法:由于新旧版本安装在不同目录,需要手动启动新版本:

bash 复制代码
# 1. 直接启动新版本(会自动绑定到相同的端口)
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -c /usr/local/openresty-1.27/nginx/conf/nginx.conf

# 2. 查看进程,应该看到两组 nginx 进程
ps aux | grep nginx | grep -v grep

# 预期输出:
# root     43158  旧版本 master
# nobody   43159  旧版本 worker
# root     <新PID>  新版本 master
# nobody   <新PID>  新版本 worker
步骤 3:优雅关闭旧版本 worker 进程
bash 复制代码
# 向旧 master 发送 WINCH 信号,优雅关闭旧 worker
sudo kill -WINCH $OLD_PID

# 等待旧 worker 处理完现有连接(通常几秒到几分钟)
sleep 5

# 查看进程状态
ps aux | grep nginx | grep -v grep

# 预期:旧 worker 进程消失,只剩旧 master
# root     43158  旧版本 master(空闲)
# root     <新PID>  新版本 master
# nobody   <新PID>  新版本 worker
步骤 4:测试新版本
bash 复制代码
# 1. 测试 HTTP 请求
curl -I http://localhost
curl http://localhost

# 2. 查看新版本日志
tail -f /usr/local/openresty-1.27/nginx/logs/error.log
tail -f /usr/local/openresty-1.27/nginx/logs/access.log

# 3. 测试 Lua 功能(如果有)
curl http://localhost/your-lua-endpoint

# 4. 检查错误日志
grep -i error /usr/local/openresty-1.27/nginx/logs/error.log
步骤 5:完全关闭旧版本或保留回滚选项

选项 A:完全关闭旧版本(确认新版本稳定后)

bash 复制代码
# 优雅关闭旧 master(发送 QUIT 信号)
sudo kill -QUIT $OLD_PID

# 验证旧进程已退出
ps aux | grep nginx | grep -v grep

选项 B:保留旧版本进程以便快速回滚(推荐在观察期内)

bash 复制代码
# 暂时不关闭旧 master,观察新版本运行一段时间(如 1 小时或 24 小时)
# 旧 master 不会占用资源,只是保留进程,方便回滚

# 如果在观察期内发现问题,可以快速回滚(见后续章节)
5.3 快速回滚(如果需要)

如果新版本出现问题,可以快速回滚:

bash 复制代码
# 1. 重新拉起旧版本的 worker 进程
sudo kill -HUP $OLD_PID

# 2. 获取新版本 master PID
NEW_PID=$(ps aux | grep "openresty-1.27" | grep master | awk '{print $2}')

# 3. 优雅关闭新版本
sudo kill -QUIT $NEW_PID

# 4. 验证回滚成功
ps aux | grep nginx | grep -v grep
/usr/local/openresty-1.25/nginx/sbin/nginx -v

方式二:替换二进制文件升级(不推荐)

不推荐原因:由于新旧版本安装在不同目录,替换二进制文件方式不适用。


方式三:停机升级(适用于可以容忍短暂停机的场景)

如果你的应用可以容忍几秒到几分钟的停机时间:

bash 复制代码
# 1. 优雅停止旧版本(等待当前连接处理完成)
sudo /usr/local/openresty-1.25/nginx/sbin/nginx -s quit

# 或使用信号(效果相同)
# sudo kill -QUIT $OLD_PID

# 2. 等待旧进程完全退出
sleep 3

# 3. 启动新版本
sudo /usr/local/openresty-1.27/nginx/sbin/nginx

# 4. 验证启动成功
ps aux | grep nginx | grep -v grep
curl -I http://localhost

六、升级验证

6.1 基础功能测试

bash 复制代码
# 1. 检查版本
/usr/local/openresty-1.27/nginx/sbin/nginx -v

# 2. 检查进程
ps aux | grep nginx

# 3. 检查端口监听
sudo lsof -i -P | grep nginx
# 或
sudo netstat -tuln | grep nginx

# 4. 测试 HTTP 请求
curl -I http://localhost
curl -v http://localhost

# 5. 测试 HTTPS(如果启用)
curl -Ik https://localhost

6.2 配置验证

bash 复制代码
# 1. 重新测试配置
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -t

# 2. 查看加载的模块
/usr/local/openresty-1.27/nginx/sbin/nginx -V 2>&1 | grep -o "with-[^ ]*"

# 3. 测试配置热重载
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -s reload

6.3 Lua 功能测试

如果你的应用使用了 Lua 脚本:

bash 复制代码
# 1. 测试 Lua 接口
curl http://localhost/lua-test-endpoint

# 2. 测试 LuaJIT
/usr/local/openresty-1.27/luajit/bin/luajit -v

# 3. 测试 Lua 模块加载(在 nginx.conf 中添加测试端点)
# location /lua-version {
#     content_by_lua_block {
#         ngx.say("LuaJIT version: ", jit.version)
#         ngx.say("OpenResty version: ", ngx.config.nginx_version)
#     }
# }

curl http://localhost/lua-version

6.4 日志检查

bash 复制代码
# 1. 查看错误日志
tail -n 100 /usr/local/openresty-1.27/nginx/logs/error.log
grep -i "error\|warn\|crit" /usr/local/openresty-1.27/nginx/logs/error.log

# 2. 查看访问日志
tail -n 100 /usr/local/openresty-1.27/nginx/logs/access.log

# 3. 实时监控日志
tail -f /usr/local/openresty-1.27/nginx/logs/error.log

# 4. 检查是否有异常请求
awk '{print $9}' /usr/local/openresty-1.27/nginx/logs/access.log | sort | uniq -c | sort -rn

6.5 性能对比测试

使用压力测试工具对比升级前后的性能:

bash 复制代码
# 安装 wrk(如果没有)
brew install wrk

# 测试新版本性能
wrk -t4 -c100 -d30s http://localhost/
# 或使用 ab
ab -n 10000 -c 100 http://localhost/

# 记录关键指标:
# - Requests/sec(每秒请求数)
# - Latency(延迟)
# - Transfer/sec(吞吐量)

# 对比旧版本的性能数据(如果之前记录过)

6.6 业务功能测试

根据你的业务场景,测试关键功能:

  • 用户登录/认证
  • API 接口调用
  • 数据库连接(Redis/MySQL)
  • 缓存功能
  • 文件上传下载
  • WebSocket 连接(如果有)
  • 代理转发功能

七、后续清理

7.1 环境清理(确认新版本稳定后)

建议观察期:运行 1-7 天后,确认无问题再清理。

bash 复制代码
# 1. 完全停止旧版本(如果还在运行)
sudo kill -QUIT $(cat /usr/local/openresty-1.25/nginx/logs/nginx.pid.oldbin 2>/dev/null)
# 或
sudo killall -9 nginx

# 2. 清理编译临时文件
rm -rf ~/openresty-build/

# 3. 选择性保留或删除旧版本目录
# 选项 A:删除旧版本(谨慎!)
# sudo rm -rf /usr/local/openresty-1.25/

# 选项 B:移动到备份目录(推荐)
sudo mv /usr/local/openresty-1.25/ ~/openresty-1.25-old-$(date +%Y%m%d)/

# 选项 C:仅删除旧版本的二进制文件,保留配置
# sudo rm -rf /usr/local/openresty-1.25/nginx/sbin/
# sudo rm -rf /usr/local/openresty-1.25/luajit/

7.2 创建启动脚本(可选)

创建一个便捷的启动脚本:

bash 复制代码
# 创建启动脚本
sudo tee /usr/local/bin/openresty-start <<'EOF'
#!/bin/bash
/usr/local/openresty-1.27/nginx/sbin/nginx "$@"
EOF

sudo chmod +x /usr/local/bin/openresty-start

# 创建符号链接(可选)
sudo ln -sf /usr/local/openresty-1.27/nginx/sbin/nginx /usr/local/bin/nginx

# 测试
openresty-start -v

7.3 配置开机自启(macOS LaunchDaemon)

bash 复制代码
# 创建 LaunchDaemon 配置文件
sudo tee /Library/LaunchDaemons/com.openresty.nginx.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.openresty.nginx</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/openresty-1.27/nginx/sbin/nginx</string>
        <string>-g</string>
        <string>daemon off;</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/usr/local/openresty-1.27/nginx/logs/launchd-error.log</string>
    <key>StandardOutPath</key>
    <string>/usr/local/openresty-1.27/nginx/logs/launchd-access.log</string>
</dict>
</plist>
EOF

# 加载 LaunchDaemon
sudo launchctl load -w /Library/LaunchDaemons/com.openresty.nginx.plist

# 验证
sudo launchctl list | grep openresty

八、常见问题与解决方案

8.1 编译失败:找不到依赖

问题

复制代码
./configure: error: the HTTP rewrite module requires the PCRE library.
./configure: error: SSL modules require the OpenSSL library.

解决方案

bash 复制代码
# macOS
brew install pcre openssl@3

# 重新配置,指定依赖路径
./configure \
  --with-cc-opt="-I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/pcre/include" \
  --with-ld-opt="-L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/pcre/lib" \
  --prefix=/usr/local/openresty-1.27

8.2 启动失败:端口被占用

问题

复制代码
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)

解决方案

bash 复制代码
# 1. 查看端口占用
sudo lsof -i :80

# 2. 如果是旧版本占用,停止旧版本
sudo /usr/local/openresty-1.25/nginx/sbin/nginx -s quit

# 3. 或者修改新版本的监听端口(临时方案)
# 编辑 /usr/local/openresty-1.27/nginx/conf/nginx.conf
# listen 8080; # 改为其他端口

8.3 配置测试失败

问题

复制代码
nginx: [emerg] unknown directive "lua_package_path" in /usr/local/openresty-1.27/nginx/conf/nginx.conf:10

解决方案

bash 复制代码
# 1. 确认 lua-nginx-module 已编译
/usr/local/openresty-1.27/nginx/sbin/nginx -V 2>&1 | grep lua

# 2. 如果没有,重新编译时确保包含 lua 模块
# OpenResty 默认包含 lua 模块,无需手动添加

# 3. 检查配置语法
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -t -c /usr/local/openresty-1.27/nginx/conf/nginx.conf

8.4 Lua 脚本报错:找不到模块

问题

复制代码
lua entry thread aborted: runtime error: module 'resty.core' not found

解决方案

bash 复制代码
# 1. 确认 LuaJIT 和 Lua 库已安装
ls -la /usr/local/openresty-1.27/lualib/
ls -la /usr/local/openresty-1.27/luajit/

# 2. 在 nginx.conf 中添加 Lua 包路径
lua_package_path "/usr/local/openresty-1.27/lualib/?.lua;/usr/local/openresty-1.27/lualib/?/init.lua;;";
lua_package_cpath "/usr/local/openresty-1.27/lualib/?.so;;";

# 3. 如果有第三方 Lua 模块,确保已复制到新版本
sudo cp -r /path/to/custom/lua/modules/* /usr/local/openresty-1.27/lualib/

8.5 权限问题

问题

复制代码
nginx: [alert] could not open error log file: open() "/usr/local/openresty-1.27/nginx/logs/error.log" failed (13: Permission denied)

解决方案

bash 复制代码
# 1. 检查目录权限
ls -la /usr/local/openresty-1.27/nginx/logs/

# 2. 修复权限
sudo chown -R root:wheel /usr/local/openresty-1.27/
sudo chmod -R 755 /usr/local/openresty-1.27/nginx/logs/

# 3. 使用 sudo 启动
sudo /usr/local/openresty-1.27/nginx/sbin/nginx

8.6 信号升级失败

问题:发送 USR2 信号后,新进程没有启动

解决方案

bash 复制代码
# 由于新旧版本在不同目录,USR2 信号可能不适用
# 使用手动启动方式(见第五章节)

# 1. 直接启动新版本
sudo /usr/local/openresty-1.27/nginx/sbin/nginx

# 2. 然后优雅关闭旧版本
sudo kill -WINCH $OLD_PID
sudo kill -QUIT $OLD_PID

九、回滚方案

9.1 紧急回滚(新版本有严重问题)

bash 复制代码
# 1. 立即停止新版本
sudo killall -9 nginx
# 或
NEW_PID=$(ps aux | grep "openresty-1.27" | grep master | awk '{print $2}')
sudo kill -9 $NEW_PID

# 2. 启动旧版本
sudo /usr/local/openresty-1.25/nginx/sbin/nginx

# 3. 验证回滚成功
ps aux | grep nginx | grep -v grep
/usr/local/openresty-1.25/nginx/sbin/nginx -v
curl -I http://localhost

9.2 优雅回滚(新版本有小问题,但可以等待)

如果旧版本 master 还在运行(步骤 5.5 选项 B):

bash 复制代码
# 1. 重新拉起旧版本 worker
sudo kill -HUP $OLD_PID

# 2. 获取新版本 PID
NEW_PID=$(ps aux | grep "openresty-1.27" | grep master | awk '{print $2}')

# 3. 优雅关闭新版本 worker
sudo kill -WINCH $NEW_PID

# 4. 等待新 worker 退出
sleep 5

# 5. 关闭新版本 master
sudo kill -QUIT $NEW_PID

# 6. 验证
ps aux | grep nginx | grep -v grep

9.3 恢复配置文件

如果新版本修改了配置文件:

bash 复制代码
# 1. 从备份恢复
BACKUP_DIR=$(ls -dt /usr/local/openresty-1.25/nginx/conf.backup_* | head -1)
sudo cp -r $BACKUP_DIR/* /usr/local/openresty-1.25/nginx/conf/

# 2. 测试配置
sudo /usr/local/openresty-1.25/nginx/sbin/nginx -t

# 3. 重新加载
sudo /usr/local/openresty-1.25/nginx/sbin/nginx -s reload

十、升级检查清单

升级前

  • 安装系统依赖(pcre、openssl、perl)
  • 备份配置文件(带时间戳)
  • 备份整个 OpenResty 目录
  • 导出当前编译参数
  • 记录运行进程和端口
  • 测试旧版本配置有效性
  • 检查 Lua 代码兼容性
  • 准备回滚方案

编译安装

  • 下载 OpenResty 1.27.1.2 源码
  • 配置编译参数(与旧版本一致)
  • 编译(make -j8)
  • 安装到独立目录(/usr/local/openresty-1.27)
  • 验证新版本可执行文件

配置迁移

  • 复制配置文件到新版本
  • 检查和更新路径引用
  • 测试新版本配置语法
  • 复制自定义 Lua 模块(如果有)

平滑升级

  • 获取旧 master 进程 PID
  • 启动新版本进程
  • 优雅关闭旧 worker 进程
  • 测试新版本功能
  • 决定关闭或保留旧 master

验证测试

  • 检查版本和进程状态
  • 测试 HTTP/HTTPS 请求
  • 验证 Lua 功能
  • 检查错误日志
  • 性能对比测试
  • 业务功能测试

后续工作

  • 监控运行 1-7 天
  • 清理旧版本文件
  • 创建启动脚本
  • 配置开机自启
  • 更新监控和告警配置
  • 文档记录升级过程
  • 通知团队成员

十一、附录

A. 目录结构对比

项目 OpenResty 1.25 OpenResty 1.27
安装根目录 /usr/local/openresty-1.25/ /usr/local/openresty-1.27/
nginx 目录 /usr/local/openresty-1.25/nginx/ /usr/local/openresty-1.27/nginx/
可执行文件 /usr/local/openresty-1.25/nginx/sbin/nginx /usr/local/openresty-1.27/nginx/sbin/nginx
配置目录 /usr/local/openresty-1.25/nginx/conf/ /usr/local/openresty-1.27/nginx/conf/
日志目录 /usr/local/openresty-1.25/nginx/logs/ /usr/local/openresty-1.27/nginx/logs/
LuaJIT /usr/local/openresty-1.25/luajit/ /usr/local/openresty-1.27/luajit/
Lua 库 /usr/local/openresty-1.25/lualib/ /usr/local/openresty-1.27/lualib/
临时文件 /usr/local/openresty-1.25/nginx/temp/ /usr/local/openresty-1.27/nginx/temp/

B. 常用命令速查

bash 复制代码
# === 版本和编译信息 ===
/usr/local/openresty-1.27/nginx/sbin/nginx -v        # 查看版本
/usr/local/openresty-1.27/nginx/sbin/nginx -V        # 查看编译参数
/usr/local/openresty-1.27/luajit/bin/luajit -v       # 查看 LuaJIT 版本

# === 配置管理 ===
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -t   # 测试配置
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -s reload  # 重载配置
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -s reopen  # 重新打开日志

# === 进程控制 ===
sudo /usr/local/openresty-1.27/nginx/sbin/nginx              # 启动
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -s quit     # 优雅停止
sudo /usr/local/openresty-1.27/nginx/sbin/nginx -s stop     # 快速停止

# === 信号控制 ===
sudo kill -QUIT <PID>    # 优雅停止
sudo kill -TERM <PID>    # 快速停止
sudo kill -HUP <PID>     # 重载配置
sudo kill -USR1 <PID>    # 重新打开日志文件
sudo kill -USR2 <PID>    # 平滑升级(启动新 master)
sudo kill -WINCH <PID>   # 优雅关闭 worker 进程

# === 进程查看 ===
ps aux | grep nginx                        # 查看进程
sudo lsof -i -P | grep nginx              # 查看监听端口
pstree -p $(cat /usr/local/openresty-1.27/nginx/logs/nginx.pid)  # 查看进程树

# === 日志查看 ===
tail -f /usr/local/openresty-1.27/nginx/logs/error.log   # 实时错误日志
tail -f /usr/local/openresty-1.27/nginx/logs/access.log  # 实时访问日志
grep -i error /usr/local/openresty-1.27/nginx/logs/error.log  # 搜索错误

C. 编译参数对比

OpenResty 1.25.3.2

bash 复制代码
--prefix=/usr/local/openresty-1.25/nginx
--with-cc-opt='-O2 -I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/pcre/include'
--with-ld-opt='-Wl,-rpath,/usr/local/openresty-1.25/luajit/lib -L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/pcre/lib'
--with-pcre-jit
--with-http_ssl_module
--with-http_v2_module
--with-http_realip_module
--with-http_stub_status_module
--with-stream
--with-stream_ssl_module
--with-stream_ssl_preread_module
--without-pcre2

OpenResty 1.27.1.2(推荐)

bash 复制代码
--prefix=/usr/local/openresty-1.27
--with-cc-opt='-O2 -I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/pcre/include'
--with-ld-opt='-Wl,-rpath,/usr/local/openresty-1.27/luajit/lib -L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/pcre/lib'
--with-pcre-jit
--with-http_ssl_module
--with-http_v2_module
--with-http_realip_module
--with-http_stub_status_module
--with-stream
--with-stream_ssl_module
--with-stream_ssl_preread_module
--without-pcre2

D. 参考资料

E. 故障排查清单

问题类型 检查项 命令
编译失败 依赖是否安装 brew list pcre openssl@3
编译日志 查看 make 输出
启动失败 端口占用 sudo lsof -i :80
配置语法 nginx -t
权限问题 ls -la /usr/local/openresty-1.27/
错误日志 tail -f logs/error.log
Lua 错误 模块路径 检查 lua_package_path
LuaJIT 版本 /usr/local/openresty-1.27/luajit/bin/luajit -v
Lua 库文件 ls -la /usr/local/openresty-1.27/lualib/
性能问题 worker 进程数 检查 worker_processes 配置
连接数 检查 worker_connections 配置
系统资源 tophtop
平滑升级失败 进程状态 `ps aux
信号发送 确认 PID 正确
日志检查 查看新旧版本日志

十二、升级时间规划建议

12.1 小型项目(个人或开发环境)

  • 总耗时:1-2 小时
  • 建议时间:任意时间
  • 步骤
    1. 备份(5 分钟)
    2. 下载编译(20-40 分钟)
    3. 配置迁移(10 分钟)
    4. 升级测试(15 分钟)
    5. 观察验证(30 分钟)

12.2 中型项目(生产环境,有备份节点)

  • 总耗时:3-4 小时
  • 建议时间:凌晨或低峰期
  • 步骤
    1. 备份和准备(15 分钟)
    2. 编译安装(30-60 分钟)
    3. 配置迁移和测试(30 分钟)
    4. 平滑升级(15 分钟)
    5. 功能验证(30 分钟)
    6. 性能测试(30 分钟)
    7. 观察期(1-2 小时)

12.3 大型项目(核心生产环境)

  • 总耗时:1-2 天
  • 建议时间:周末或维护窗口
  • 步骤
    1. Day 1 准备阶段 (2-3 小时)
      • 完整备份
      • 在测试环境验证
      • 编译安装到生产环境
      • 配置迁移和测试
    2. Day 1 升级阶段 (1 小时)
      • 平滑升级
      • 基础功能验证
    3. Day 1-2 观察期 (24-48 小时)
      • 持续监控日志
      • 性能指标对比
      • 业务数据验证
    4. Day 2 清理阶段 (30 分钟)
      • 确认稳定后清理旧版本

文档版本 :v2.0(编译安装版)
创建时间 :2025-11-20
适用环境 :macOS / Linux
当前版本 :OpenResty 1.25.3.2
目标版本 :OpenResty 1.27.1.2
安装方式:源码编译安装

相关推荐
IMPYLH2 小时前
Lua 的 pairs 函数
开发语言·笔记·后端·junit·单元测试·lua
安冬的码畜日常5 小时前
【JUnit实战3_35】第二十二章:用 JUnit 5 实现测试金字塔策略
测试工具·junit·单元测试·集成测试·系统测试·bdd·测试金字塔
IMPYLH4 天前
Lua 的 collectgarbage 函数
开发语言·笔记·junit·单元测试·lua
IMPYLH4 天前
Lua 的 assert 函数
开发语言·笔记·junit·单元测试·lua
倚肆6 天前
Spring Boot 日志系统全面详解
spring boot·junit·单元测试
百***48937 天前
Nginx实现接口复制
运维·nginx·junit
安冬的码畜日常9 天前
【JUnit实战3_33】第二十章:用 JUnit 5 进行测试驱动开发(TDD)(下)——TDD 项目的重构过程及新功能的开发实战
测试工具·junit·单元测试·测试驱动开发·tdd·junit5·test-driven
百***34139 天前
Nginx实现接口复制
运维·nginx·junit
张3蜂10 天前
import org.junit.Test; 是什么
数据库·junit