news 2026/4/18 6:16:39

Nginx迁移OpenResty+Lua,实现负载动态上下线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Nginx迁移OpenResty+Lua,实现负载动态上下线
避坑指南:

1.尝试过ngx_http_dyups_module模块,感觉不太好用,OpenResty完全兼容nginx果断采用OpenResty方案

2.迁移最好是找个新机器,测试没问题再切流量

OpenResty是什么

淘宝团队(章亦春)基于官方 Nginx 打包的发行版

  • 内置LuaJIT(极快的脚本引擎)
  • 内置lua-nginx-module
  • 内置几百个生产库(redis、mysql、dns、shared dict、upstream 管理等)

OpenResty 底层就是原汁原味 Nginx,完全兼容所有 Nginx 配置所有 Nginx 配置直接复制到 OpenResty 100% 能用

特点
  • 可以用 Lua 代码动态修改 upstream
  • 不需要 reload、不需要改配置、0 抖动
  • 可以写:
    • 动态上下线节点 API
    • 限流、熔断、灰度、AB 测试
    • 动态负载、流量染色、鉴权
  • 性能几乎和 Nginx 一致(LuaJIT 超快)
迁移全流程

1. 迁移前备份(必做!回滚用)

# 1. 备份原有 nginx 配置 cp -r /usr/local/nginx/conf /usr/local/nginx/conf.bak$(date +%Y%m%d) # 2. 备份原有 nginx 二进制 cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak # 3. 查看原有 nginx 编译参数(后续 openresty 保持一致) nginx -V

2.安装 OpenResty 依赖

# CentOS yum install -y pcre-devel openssl-devel gcc curl make # Ubuntu apt install -y libpcre3-dev libssl-dev gcc curl make

3.下载并编译 OpenResty(注意版本)

# 下载 cd /usr/local/src wget https://openresty.org/download/openresty-1.21.4.1.tar.gz tar -zxvf openresty-1.21.4.1.tar.gz cd openresty-1.21.4.1 # 编译配置(和你原 Nginx 1.21.4 完全兼容) ./configure \ --prefix=/usr/local/openresty \ --with-http_ssl_module \ --with-http_realip_module \ --with-http_gzip_static_module \ --with-http_stub_status_module # 编译安装 make -j4 && make install

5.配置迁移

# 复制你原有 Nginx 配置到 OpenResty cp -rf /usr/local/nginx/conf/* /usr/local/openresty/nginx/conf/ #平滑关闭旧 Nginx,启动 OpenResty(零停机) # 平滑停止旧 Nginx(等待所有请求执行完,不中断) /usr/local/nginx/sbin/nginx -s quit # 启动 OpenResty(等价于 nginx,完全兼容) /usr/local/openresty/nginx/sbin/nginx # 查看版本 → 显示 openresty/1.21.4.1 即成功 /usr/local/openresty/nginx/sbin/nginx -v # 测试业务 → 原有网站/接口完全正常访问 curl http://你的域名
核心配置:动态 Upstream(API 上下线,无需 reload)

1. 配置文件:/usr/local/openresty/nginx/conf/nginx.conf

pid /usr/local/openresty/nginx/logs/nginx.pid; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; # 业务上游集群 upstream pos_gateway { server 127.0.0.1:8089; server 127.0.0.1:8088; } # 业务入口 8087 server { listen 8087; location / { proxy_pass http://pos_gateway; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } # 动态上下线 API服务(JSON输出+UTF8+节点保护) server { listen 8086; # 1. 查看节点状态 - 标准JSON输出 location /upstream/status { content_by_lua_block { -- 设置UTF-8编码,解决中文乱码 ngx.header.content_type = "application/json; charset=utf-8" local ngx_upstream = require "ngx.upstream" local cjson = require "cjson" local peers = ngx_upstream.get_primary_peers("pos_gateway") local result = { code = 200, msg = "查询成功", data = peers } ngx.say(cjson.encode(result)) } } # 2. 统一操作接口:up上线/down下线(JSON+保护机制) location /upstream/operate { content_by_lua_block { -- 核心:设置UTF8编码,彻底解决中文乱码 ngx.header.content_type = "application/json; charset=utf-8" local ngx_upstream = require "ngx.upstream" local cjson = require "cjson" -- 获取参数 local action = ngx.var.arg_action local ip = ngx.var.arg_ip local port = ngx.var.arg_port -- 统一JSON返回对象 local res = {code=500, msg="", data=nil} -- 参数校验 if not action or not ip or not port then res.msg = "参数错误:请传入 action=up/down、ip、port" ngx.say(cjson.encode(res)) return end if action ~= "up" and action ~= "down" then res.msg = "参数错误:action仅支持 up/down" ngx.say(cjson.encode(res)) return end local target_server = ip .. ":" .. port local peers = ngx_upstream.get_primary_peers("pos_gateway") local peer_index = nil local target_is_online = false -- 匹配目标节点 for i, peer in ipairs(peers) do if peer.name == target_server then peer_index = i - 1 target_is_online = not peer.down break end end if not peer_index then res.msg = "操作失败:未找到节点 " .. target_server ngx.say(cjson.encode(res)) return end -- 核心保护:禁止下线最后一个在线节点 if action == "down" then local online_count = 0 for _, peer in ipairs(peers) do if not peer.down then online_count = online_count + 1 end end if online_count == 1 and target_is_online then res.msg = "禁止操作:当前仅有一个节点在线,不允许下线" ngx.say(cjson.encode(res)) return end end -- 执行上下线操作 local is_down = (action == "down") local ok, err = ngx_upstream.set_peer_down("pos_gateway", false, peer_index, is_down) if ok then res.code = 200 res.msg = "操作成功:节点 " .. target_server .. (is_down and " 已下线" or " 已上线") else res.msg = "操作失败:" .. err end ngx.say(cjson.encode(res)) } } } # 测试服务 8089 server { listen 8089; location / { return 200 "8089"; } } # 测试服务 8088 server { listen 8088; location / { return 200 "8088"; } } }

2. 测试验证

# 1. 查询节点状态 curl http://127.0.0.1:8086/upstream/status # 2. 下线8089节点 curl "http://127.0.0.1:8086/upstream/operate?action=down&ip=127.0.0.1&port=8089" # 3. 尝试下线最后一个节点8088(触发保护) curl "http://127.0.0.1:8086/upstream/operate?action=down&ip=127.0.0.1&port=8088" # 4. 上线8089节点 curl "http://127.0.0.1:8086/upstream/operate?action=up&ip=127.0.0.1&port=8089" # 5. 业务测试 curl http://127.0.0.1:8087 // 成功 {"code":200,"msg":"操作成功:节点 127.0.0.1:8089 已下线","data":null} // 保护提示 {"code":500,"msg":"禁止操作:当前仅有一个节点在线,不允许下线","data":null} // 状态查询 {"code":200,"msg":"查询成功","data":[{"name":"127.0.0.1:8089","down":false},...]}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 6:16:38

内网 Windows 极客指南:从零跑起 OpenClaw 离线开发环境

🔧 内网 Windows 极客指南:从零跑起 OpenClaw 离线开发环境 没有互联网,也能优雅地装上 Node.js、pnpm 和整个 OpenClaw 项目 —— 一份写给小白、也写给所有爱折腾的人的离线部署手记 你是否遇到过这种情景:公司的开发机在纯内网…

作者头像 李华
网站建设 2026/4/18 6:12:40

Intv_ai_mk11前端设计(Frontend-Design)集成:构建美观的对话交互界面

Intv_ai_mk11前端设计集成:构建美观的对话交互界面 1. 为什么前端设计对AI对话体验至关重要 想象一下,你正在和一个智能助手对话,但界面卡顿、消息显示混乱、操作不直观——即使后端AI再强大,这种体验也会让人很快失去耐心。这就…

作者头像 李华
网站建设 2026/4/18 6:08:23

锤爆国内两大 AI 模型!专治 AI 胡说八道

我用原创的双熵互校认知框架,直接把文心、千问两大顶流 AI 聊到:上头、失忆、沉默、认真思考,最后还不得不承认 ——这东西是真的强。专治:AI 逻辑漂移前后矛盾记忆错乱一本正经胡说八道不改模型、不加参数,纯架构级 “…

作者头像 李华
网站建设 2026/4/18 6:08:22

SGMII链路调试实战:从时钟对齐到数据捕获的完整排障指南

1. SGMII链路基础与常见问题场景 SGMII(Serial Gigabit Media Independent Interface)是串行千兆媒体独立接口的简称,它通过单对差分线实现全双工通信,相比传统的GMII接口能大幅减少引脚数量。在实际项目中,我经常遇到…

作者头像 李华
网站建设 2026/4/18 6:06:33

vLLM-v0.17.1与Node.js环境集成:构建高性能AI API服务

vLLM-v0.17.1与Node.js环境集成:构建高性能AI API服务 1. 为什么需要vLLM与Node.js集成 在AI服务开发中,我们经常面临一个核心矛盾:Python生态拥有最强大的模型推理能力,而Web开发却主要依赖JavaScript/Node.js生态。vLLM作为当…

作者头像 李华
网站建设 2026/4/18 6:05:19

SerialPlot终极指南:3分钟快速上手串口数据可视化工具

SerialPlot终极指南:3分钟快速上手串口数据可视化工具 【免费下载链接】serialplot Small and simple software for plotting data from serial port in realtime. 项目地址: https://gitcode.com/gh_mirrors/se/serialplot 你是否曾面对串口输出的海量数字数…

作者头像 李华