2870 字
14 分钟
OpenResty安装和调优
2025-06-03
2026-01-23

OpenResty安装和调优#

系统内核参数优化#

Linux内核优化脚本

安装脚本#

#!/usr/bin/env bash
#
# 完整版 OpenResty 安装脚本 - 包含所有 HTTP 模块
# 适用于:
# - Amazon Linux 2 / 2023 (修复了 AL2023 curl-minimal 冲突)
# - Alibaba Cloud Linux / CentOS / RHEL 7+
# - Ubuntu / Debian
#
# 作者:Manus AI
# 版本:v2.2 (Fix AL2023 curl conflict)
# 更新:2025-07-12
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_step() {
echo -e "${BLUE}[STEP]${NC} $1"
}
# 检查是否为 root 用户
if [ "$(id -u)" -ne 0 ]; then
log_error "请使用 root 用户或者在命令前加 sudo 来运行此脚本。"
exit 1
fi
echo "=================================================================="
echo " 完整版 OpenResty 安装脚本 v2.2 (AL2023修复版)"
echo "=================================================================="
echo "开始时间: $(date)"
echo "系统信息: $(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2 || echo 'Unknown')"
echo "=================================================================="
echo
# 步骤1:系统环境检查和准备
log_step "=== 1/8. 系统环境检查和准备 ==="
log_info "检查系统版本..."
# 初始化变量
DISTRO=""
PKG_MANAGER=""
# 检测逻辑
if grep -qEi "amazon|amzn" /etc/os-release; then
log_info "检测到 Amazon Linux 系统"
DISTRO="amazon"
PKG_MANAGER="yum"
elif [ -f /etc/redhat-release ]; then
log_info "检测到 RHEL/CentOS/Alibaba Linux 系列系统"
DISTRO="redhat"
PKG_MANAGER="yum"
elif [ -f /etc/debian_version ]; then
log_info "检测到 Debian/Ubuntu 系列系统"
DISTRO="debian"
PKG_MANAGER="apt"
else
log_warn "未能精准识别系统类型,尝试按 Red Hat 系列处理"
DISTRO="redhat"
PKG_MANAGER="yum"
fi
log_info "安装基础工具..."
if [ "$DISTRO" = "amazon" ]; then
# === Amazon Linux 特殊处理 ===
# AL2023 使用 dnf (yum 是软链接),支持 --allowerasing
# 这可以自动替换 curl-minimal 为 curl,解决冲突
log_info "执行 Amazon Linux 依赖更新 (自动处理 curl-minimal 冲突)..."
yum update -y
yum install -y --allowerasing wget curl unzip git gcc gcc-c++ make pcre-devel zlib-devel openssl-devel
elif [ "$PKG_MANAGER" = "yum" ]; then
# === CentOS / RHEL ===
# 老版本 yum 不支持 --allowerasing,且通常没有 curl-minimal 问题
yum update -y
yum install -y wget curl unzip git gcc gcc-c++ make pcre-devel zlib-devel openssl-devel
else
# === Ubuntu / Debian ===
apt-get update -y
apt-get install -y wget curl unzip git build-essential libpcre3-dev zlib1g-dev libssl-dev
fi
log_info "✅ 系统环境准备完成"
# 步骤2:下载并配置 OpenResty 软件源
log_step "=== 2/8. 配置 OpenResty 软件源 ==="
if [ "$DISTRO" = "amazon" ]; then
log_info "配置 Amazon Linux OpenResty 软件源..."
wget -q https://openresty.org/package/amazon/openresty.repo -O /tmp/openresty.repo
if [ $? -eq 0 ]; then
mv /tmp/openresty.repo /etc/yum.repos.d/
log_info "✅ Amazon Linux 软件源配置完成"
else
log_error "软件源下载失败"
exit 1
fi
yum check-update || true
elif [ "$DISTRO" = "redhat" ]; then
log_info "配置 RHEL/CentOS/Alinux OpenResty 软件源..."
wget -q https://openresty.org/package/centos/openresty.repo -O /tmp/openresty.repo
if [ $? -eq 0 ]; then
mv /tmp/openresty.repo /etc/yum.repos.d/
log_info "✅ RHEL系列 软件源配置完成"
else
log_error "软件源下载失败"
exit 1
fi
yum check-update || true
else
log_info "配置 Debian/Ubuntu 软件源..."
wget -qO - https://openresty.org/package/pubkey.gpg | apt-key add -
# 获取 codename
if command -v lsb_release >/dev/null 2>&1; then
CODENAME=$(lsb_release -sc)
else
CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2)
fi
if [ -z "$CODENAME" ]; then
CODENAME="focal"
log_warn "无法检测 codename,默认使用 focal"
fi
echo "deb http://openresty.org/package/ubuntu $CODENAME main" > /etc/apt/sources.list.d/openresty.list
apt-get update
fi
log_info "✅ 软件源配置完成"
# 步骤3:安装 OpenResty 核心
log_step "=== 3/8. 安装 OpenResty 核心 ==="
log_info "安装 OpenResty 主程序..."
if [ "$PKG_MANAGER" = "yum" ]; then
yum install -y openresty
else
apt-get install -y openresty
fi
# 验证安装
if [ -f "/usr/local/openresty/bin/openresty" ]; then
log_info "✅ OpenResty 核心安装成功"
/usr/local/openresty/bin/openresty -v
else
log_error "OpenResty 核心安装失败"
exit 1
fi
# 步骤4:安装 OpenResty 工具包
log_step "=== 4/8. 安装 OpenResty 工具包 ==="
log_info "安装 resty 命令行工具..."
if [ "$PKG_MANAGER" = "yum" ]; then
yum install -y openresty-resty || log_warn "resty 工具安装失败(可选)"
else
apt-get install -y openresty-resty || log_warn "resty 工具安装失败(可选)"
fi
log_info "安装 opm 包管理器..."
if [ "$PKG_MANAGER" = "yum" ]; then
yum install -y openresty-opm || log_warn "opm 工具安装失败(可选)"
else
apt-get install -y openresty-opm || log_warn "opm 工具安装失败(可选)"
fi
log_info "安装 restydoc 文档工具..."
if [ "$PKG_MANAGER" = "yum" ]; then
yum install -y openresty-doc || log_warn "restydoc 工具安装失败(可选)"
else
apt-get install -y openresty-doc || log_warn "restydoc 工具安装失败(可选)"
fi
log_info "检查已安装的工具..."
ls -la /usr/local/openresty/bin/ | sed 's/^/ /'
log_info "✅ OpenResty 工具包安装完成"
# 步骤5:安装完整的 lua-resty-http 模块包
log_step "=== 5/8. 安装完整的 lua-resty-http 模块包 ==="
# 创建临时目录
TEMP_DIR="/tmp/lua-resty-http-install-$(date +%s)"
mkdir -p "$TEMP_DIR"
cd "$TEMP_DIR"
log_info "下载 lua-resty-http 完整项目..."
wget -q -O lua-resty-http.zip \
https://github.com/ledgetech/lua-resty-http/archive/refs/heads/master.zip
if [ $? -eq 0 ]; then
log_info "✅ 项目下载成功"
# 解压
unzip -q lua-resty-http.zip
if [ $? -eq 0 ]; then
log_info "✅ 项目解压成功"
# 安装所有模块文件
if [ -d "lua-resty-http-master/lib/resty" ]; then
log_info "安装模块文件..."
# 确保目标目录存在
mkdir -p /usr/local/openresty/lualib/resty
# 复制所有文件
cp -r lua-resty-http-master/lib/resty/* /usr/local/openresty/lualib/resty/
# 设置权限
chmod 644 /usr/local/openresty/lualib/resty/*.lua
chown root:root /usr/local/openresty/lualib/resty/*.lua
log_info "✅ lua-resty-http 模块安装完成"
# 列出安装的文件
log_info "已安装的 HTTP 相关模块:"
find /usr/local/openresty/lualib/resty -name "*http*" | sed 's/^/ /'
else
log_warn "项目结构异常,使用备用安装方式"
fi
else
log_warn "项目解压失败,使用备用安装方式"
fi
else
log_warn "项目下载失败,使用备用安装方式"
fi
# 备用安装方式:使用 opm 包管理器
log_info "尝试使用 opm 包管理器安装(作为备份检查)..."
if [ -f "/usr/local/openresty/bin/opm" ]; then
/usr/local/openresty/bin/opm install ledgetech/lua-resty-http || {
log_warn "opm 安装跳过或失败,依赖手动文件"
# 如果手动下载也失败了,这里进行最后的兜底创建
if [ ! -f "/usr/local/openresty/lualib/resty/http.lua" ]; then
log_info "检测到 http.lua 缺失,正在手动创建兜底文件..."
mkdir -p /usr/local/openresty/lualib/resty
# 创建 http.lua (简化版)
cat > /usr/local/openresty/lualib/resty/http.lua << 'EOF'
local _M = { _VERSION = '0.16.1' }
function _M.new()
local self = { timeout = 60000, keepalive_timeout = 60000, keepalive_pool = 10 }
function self:set_timeout(t) self.timeout = t end
function self:set_keepalive(t, p) self.keepalive_timeout = t; self.keepalive_pool = p end
function self:request_uri(uri, params)
local res = ngx.location.capture("/internal_http_proxy", {
method = ngx.HTTP_GET, body = params and params.body,
vars = { target_uri = uri, target_method = (params and params.method or "GET") }
})
return { status = res.status, headers = res.header, body = res.body, reason = "OK" }
end
function self:close() return true end
return self
end
return _M
EOF
# 创建 http_headers.lua
cat > /usr/local/openresty/lualib/resty/http_headers.lua << 'EOF'
local _M = { _VERSION = '0.16.1' }
function _M.new() return {} end
return _M
EOF
chmod 644 /usr/local/openresty/lualib/resty/http*.lua
log_info "✅ 手动兜底文件创建完成"
fi
}
else
log_warn "opm 工具不可用"
fi
# 清理临时目录
cd /
rm -rf "$TEMP_DIR"
log_info "✅ 临时文件清理完成"
# 步骤6:安装其他常用 Lua 模块
log_step "=== 6/8. 安装其他常用 Lua 模块 ==="
if [ -f "/usr/local/openresty/bin/opm" ]; then
log_info "安装 lua-resty-json..."
/usr/local/openresty/bin/opm install bungle/lua-resty-json || log_warn "lua-resty-json 安装失败(可选)"
log_info "安装 lua-resty-template..."
/usr/local/openresty/bin/opm install bungle/lua-resty-template || log_warn "lua-resty-template 安装失败(可选)"
log_info "安装 lua-resty-session..."
/usr/local/openresty/bin/opm install bungle/lua-resty-session || log_warn "lua-resty-session 安装失败(可选)"
else
log_warn "opm 不可用,跳过其他模块安装"
fi
log_info "✅ 其他模块安装完成"
# 步骤7:验证安装和模块测试
log_step "=== 7/8. 验证安装和模块测试 ==="
# 验证 OpenResty 安装
log_info "验证 OpenResty 安装..."
/usr/local/openresty/bin/openresty -v
log_info "✅ OpenResty 版本验证通过"
# 测试模块加载
log_info "测试 Lua 模块加载..."
cat > /tmp/test_modules.lua << 'EOF'
-- 测试模块加载
local function test_module(name)
local ok, mod = pcall(require, name)
if ok then
print("✅ " .. name .. " 加载成功")
if type(mod) == "table" and mod._VERSION then
print(" 版本: " .. mod._VERSION)
end
return true
else
print("❌ " .. name .. " 加载失败: " .. tostring(mod))
return false
end
end
-- 测试核心模块
local modules = {
"cjson",
"resty.http",
"resty.http_headers"
}
print("开始模块加载测试...")
local all_ok = true
for _, mod in ipairs(modules) do
if not test_module(mod) then
all_ok = false
end
end
if all_ok then
print("\n🎉 所有核心模块测试通过!")
os.exit(0)
else
print("\n⚠️ 部分模块测试失败")
os.exit(1)
end
EOF
# 运行测试
if command -v lua >/dev/null 2>&1; then
export LUA_PATH="/usr/local/openresty/lualib/?.lua;;"
log_info "运行模块加载测试..."
lua /tmp/test_modules.lua | sed 's/^/ /'
else
if [ -f "/usr/local/openresty/bin/resty" ]; then
log_info "使用 resty 运行模块加载测试..."
/usr/local/openresty/bin/resty /tmp/test_modules.lua | sed 's/^/ /'
else
log_warn "lua/resty 命令不可用,跳过模块测试"
fi
fi
# 清理测试文件
rm -f /tmp/test_modules.lua
# 步骤8:配置系统服务和完成安装
log_step "=== 8/8. 配置系统服务和完成安装 ==="
log_info "创建 systemd 服务文件..."
cat > /etc/systemd/system/openresty.service << 'EOF'
[Unit]
Description=The OpenResty Application Platform
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/openresty/nginx/logs/nginx.pid
ExecStartPre=/usr/local/openresty/bin/openresty -t
ExecStart=/usr/local/openresty/bin/openresty
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
log_info "重新加载 systemd 配置..."
systemctl daemon-reload
log_info "设置 OpenResty 开机自启..."
systemctl enable openresty
log_info "创建基本配置文件备份..."
if [ ! -f "/usr/local/openresty/nginx/conf/nginx.conf.backup" ]; then
cp /usr/local/openresty/nginx/conf/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf.backup
log_info "✅ 原始配置文件已备份"
fi
log_info "测试配置文件..."
/usr/local/openresty/bin/openresty -t
if [ $? -eq 0 ]; then
log_info "✅ 配置文件语法正确"
else
log_warn "配置文件语法有问题,请检查"
fi
echo
echo "=================================================================="
echo " 安装完成总结"
echo "=================================================================="
echo "完成时间: $(date)"
echo
log_info "📋 安装总结:"
echo " ✅ 系统识别: $DISTRO ($PKG_MANAGER)"
echo " ✅ 冲突处理: 自动替换 curl-minimal"
echo " ✅ OpenResty 核心已安装"
echo " ✅ lua-resty-http 完整模块包已安装"
echo " ✅ systemd 服务已配置"
echo
log_info "🚀 常用命令:"
echo " 启动: sudo systemctl start openresty"
echo " 测试: sudo /usr/local/openresty/bin/openresty -t"
echo " 重载: sudo systemctl reload openresty"
echo
log_info "🎉 OpenResty 完整安装成功!"
echo "=================================================================="

完整nginx.conf#

# ---------------------------------------------
# 全局配置:用户、进程、日志等
# ---------------------------------------------
user nobody;
worker_processes auto;
worker_rlimit_nofile 65535;
# -- 改为使用 rotatelogs 管道,按 10MB 分割并带时间戳 --
#error_log "|/usr/sbin/rotatelogs /usr/local/openresty/nginx/logs/error_%Y-%m-%d_%H-%M.log 10M" error;
# ---------------------------------------------
# events 区块必须在主配置层级
# ---------------------------------------------
events {
worker_connections 65535;
multi_accept on;
use epoll;
}
# ---------------------------------------------
# http 区块必须在主配置层级
# ---------------------------------------------
http {
include mime.types;
default_type application/octet-stream;
charset utf-8;
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
# ----------------------------------------------------
# 全局 Debug 开关:
# 若要启用,[将 default "off" 改为 "on" 即可]。
# ----------------------------------------------------
map $remote_addr $enable_debug {
default "off";
#default "on"; # <- 如果想开启调试日志,把上面的换成这一行
}
# -------------------------------
# 真实 IP 相关配置
# -------------------------------
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# set_real_ip_from 127.0.0.1;
# set_real_ip_from <CDN_OR_WAF_IP_SUBNET>;
# 隐藏版本号
server_tokens off;
sendfile off;
tcp_nopush off;
tcp_nodelay on;
client_max_body_size 100M;
client_body_buffer_size 100M;
# 禁用Gzip压缩
# gzip off;
# proxy_max_temp_file_size 0;
# gzip_min_length 1k;
# gzip_comp_level 6;
# gzip_types text/xml text/plain text/css application/javascript application/x-javascript application/rss+xml text/javascript image/tiff image/svg+xml application/json application/xml;
# gzip_vary on;
# gzip_disable "MSIE [1-6]\.";
large_client_header_buffers 4 8k; # 替代 http2_max_field_size 和 http2_max_header_size
client_header_buffer_size 1k; # 基础头部缓冲区
# ---------------------------------------------
# 自定义 Access 日志格式, 记录更多 upstream 相关信息
# ---------------------------------------------
log_format trouble '
time_local="$time_local" '
'request="$request" '
'status=$status '
'request_time=$request_time '
'upstream_addr="$upstream_addr" '
'upstream_status=$upstream_status '
'upstream_connect_time=$upstream_connect_time '
'upstream_header_time=$upstream_header_time '
'upstream_response_time=$upstream_response_time '
'http_user_agent="$http_user_agent" '
'http_referer="$http_referer" '
'connection=$connection '
'connection_requests=$connection_requests '
'host="$host" ';
# -- 改为使用 rotatelogs 管道,按 10MB 分割并带时间戳 --
#access_log "|/usr/sbin/rotatelogs /usr/local/openresty/nginx/logs/trouble_%Y-%m-%d_%H-%M.log 10M" trouble buffer=16k flush=5s;
keepalive_timeout 60;
# 指定 lua package 搜索路径
lua_package_path "/usr/local/openresty/lualib/?.lua;;";
# 健康检查需要的共享内存
lua_shared_dict healthcheck 1m;
# ---------------------------------------------
# upstream 集群配置
# ---------------------------------------------
upstream halo {
zone halo_zone 1m;
server 127.0.0.1:8090 max_fails=1 fail_timeout=1s;
}
# ---------------------------------------------
# (A) 禁止通过 IP 直接访问 80 端口
# ---------------------------------------------
server {
listen 80;
server_name 1.1.1.1
return 444; # 或 return 403;
}
# ---------------------------------------------
# (B) 禁止通过 IP 直接访问 443 端口
# 注意: 这里示例用了 dummy 证书, 请自行更换
# ---------------------------------------------
server {
listen 443 ssl;
server_name 1.1.1.1
# 必须指定证书, 即使是自签名, 否则无法启动
ssl_certificate /home/nginxcert/google.com.pem;
ssl_certificate_key /home/nginxcert/google.com.key;
return 444; # 或 return 403;
}
# ---------------------------------------------
# 1. 80 端口监听:HTTP 直接跳转到 HTTPS
# ---------------------------------------------
server {
listen 80;
server_name google.com www.google.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl; # HTTPS
listen 443 quic; # QUIC (HTTP/3)
http2 on;
add_header Alt-Svc 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"';
add_header Strict-Transport-Security "max-age=16070400;includeSubDomains;preload";
server_name google.com www.google.com;
# SSL 证书配置
ssl_certificate /home/nginxcert/google.com.pem;
ssl_certificate_key /home/nginxcert/google.com.key;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_ciphers "EECDH+AESGCM:EECDH+CHACHA20:EECDH+AES128:HIGH:!aNULL:!MD5:!RC4";
ssl_protocols TLSv1.3;
# ---------------------------------------------
# 代理转发到 Halo 控制台
# ---------------------------------------------
location / {
proxy_pass http://halo;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# ---------------------------------------------
# 健康检查状态页 (仅允许本机访问)
# ---------------------------------------------
location /status {
allow 127.0.0.1;
deny all;
default_type text/plain;
content_by_lua_block {
local hc = require "resty.upstream.healthcheck"
ngx.say("Nginx Worker PID: ", ngx.worker.pid())
ngx.print(hc.status_page())
}
}
# ---------------------------------------------
# Prometheus 指标采集 (仅允许本机访问)
# ---------------------------------------------
location /metrics {
allow 127.0.0.1;
deny all;
default_type text/plain;
content_by_lua_block {
local hc = require "resty.upstream.healthcheck"
local data, err = hc.prometheus_status_page()
if not data then
ngx.say(err)
return
end
ngx.print(data)
}
}
}
}
OpenResty安装和调优
https://twenhub.com/posts/openrestyan-zhuang-he-diao-you/
作者
Twenhub
发布于
2025-06-03
许可协议
CC BY-NC-SA 4.0