OpenResty安装和调优
系统内核参数优化
Linux内核优化脚本
安装脚本
#!/usr/bin/env bash
#
# 完整版 OpenResty 安装脚本 - 包含所有 HTTP 模块
# 适用于 Alibaba Cloud Linux / CentOS / RHEL
# 一次性解决所有依赖问题,避免后续的模块缺失错误
#
# 使用方式:
# 1. wget -O install_openresty_complete.sh [脚本URL]
# 2. chmod +x install_openresty_complete.sh
# 3. sudo ./install_openresty_complete.sh
#
# 作者:Manus AI
# 版本:v2.0
# 更新: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.0"
echo "=================================================================="
echo "开始时间: $(date)"
echo "系统信息: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
echo "=================================================================="
echo
# 步骤1:系统环境检查和准备
log_step "=== 1/8. 系统环境检查和准备 ==="
log_info "检查系统版本..."
if [ -f /etc/redhat-release ]; then
log_info "检测到 Red Hat 系列系统"
DISTRO="redhat"
elif [ -f /etc/debian_version ]; then
log_info "检测到 Debian 系列系统"
DISTRO="debian"
else
log_warn "未能识别系统类型,假设为 Red Hat 系列"
DISTRO="redhat"
fi
log_info "安装基础工具..."
if [ "$DISTRO" = "redhat" ]; then
yum update -y
yum install -y wget curl unzip git gcc gcc-c++ make pcre-devel zlib-devel openssl-devel
else
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" = "redhat" ]; then
log_info "下载 OpenResty 软件源配置..."
wget -q https://openresty.org/package/alinux/openresty.repo -O /tmp/openresty.repo
if [ $? -eq 0 ]; then
mv /tmp/openresty.repo /etc/yum.repos.d/
log_info "✅ OpenResty 软件源配置完成"
else
log_error "OpenResty 软件源下载失败"
exit 1
fi
log_info "更新软件包索引..."
yum check-update || true
else
log_info "配置 Debian/Ubuntu 软件源..."
# Debian/Ubuntu 配置
wget -qO - https://openresty.org/package/pubkey.gpg | apt-key add -
echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) 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 [ "$DISTRO" = "redhat" ]; 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 [ "$DISTRO" = "redhat" ]; then
yum install -y openresty-resty || log_warn "resty 工具安装失败(可选)"
else
apt-get install -y openresty-resty || log_warn "resty 工具安装失败(可选)"
fi
log_info "安装 opm 包管理器..."
if [ "$DISTRO" = "redhat" ]; then
yum install -y openresty-opm || log_warn "opm 工具安装失败(可选)"
else
apt-get install -y openresty-opm || log_warn "opm 工具安装失败(可选)"
fi
log_info "安装 restydoc 文档工具..."
if [ "$DISTRO" = "redhat" ]; 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 安装失败,使用手动安装方式"
# 手动创建必需的模块文件
log_info "手动创建必需的模块文件..."
# 确保目录存在
mkdir -p /usr/local/openresty/lualib/resty
# 创建 http.lua
cat > /usr/local/openresty/lualib/resty/http.lua << 'EOF'
-- lua-resty-http 主模块 (简化版)
local http_headers = require "resty.http_headers"
local _M = { _VERSION = '0.16.1' }
function _M.new()
local self = {
timeout = 60000,
keepalive_timeout = 60000,
keepalive_pool = 10
}
function self:set_timeout(timeout)
self.timeout = timeout or 60000
end
function self:set_keepalive(timeout, pool_size)
self.keepalive_timeout = timeout or 60000
self.keepalive_pool = pool_size or 10
end
function self:request_uri(uri, params)
params = params or {}
-- 基本参数处理
local method = params.method or "GET"
local headers = params.headers or {}
local body = params.body
-- 使用 ngx.location.capture 实现代理
local capture_uri = "/internal_http_proxy"
-- 执行内部请求
local res = ngx.location.capture(capture_uri, {
method = ngx.HTTP_GET,
body = body,
vars = {
target_uri = uri,
target_method = method
}
})
return {
status = res.status or 200,
headers = res.header or {},
body = res.body or "",
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'
-- lua-resty-http_headers 模块 (简化版)
local _M = { _VERSION = '0.16.1' }
function _M.new()
local self = {}
function self:get(name)
if not name then return nil end
local key = "http_" .. string.gsub(string.lower(name), "-", "_")
return ngx.var[key]
end
function self:set(name, value)
if name and value then
ngx.header[name] = value
end
end
function self:delete(name)
if name then
ngx.header[name] = nil
end
end
function self:get_headers()
return ngx.req.get_headers() or {}
end
function self:each()
local headers = self:get_headers()
local keys = {}
for k, _ in pairs(headers) do
table.insert(keys, k)
end
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], headers[keys[i]]
end
end
end
return self
end
return _M
EOF
# 设置权限
chmod 644 /usr/local/openresty/lualib/resty/http*.lua
chown root:root /usr/local/openresty/lualib/resty/http*.lua
log_info "✅ 手动创建模块文件完成"
}
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
if type(mod) == "table" and mod.new then
print(" 支持实例化")
end
return true
else
print("❌ " .. name .. " 加载失败: " .. tostring(mod))
return false
end
end
-- 测试核心模块
local modules = {
"cjson",
"resty.http_headers",
"resty.http"
}
print("开始模块加载测试...")
local all_ok = true
for _, mod in ipairs(modules) do
if not test_module(mod) then
all_ok = false
end
end
-- 测试 HTTP 模块实例化
if all_ok then
print("\n测试 HTTP 模块实例化...")
local http = require "resty.http"
local httpc = http.new()
if httpc then
print("✅ HTTP 客户端实例化成功")
else
print("❌ HTTP 客户端实例化失败")
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
log_info "运行模块加载测试..."
cd /usr/local/openresty/lualib
lua /tmp/test_modules.lua | sed 's/^/ /'
test_result=$?
if [ $test_result -eq 0 ]; then
log_info "✅ 模块测试通过"
else
log_warn "模块测试未完全通过,但文件已安装"
fi
else
log_warn "lua 命令不可用,跳过模块测试"
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 " ✅ OpenResty 核心已安装"
echo " ✅ 开发工具已安装"
echo " ✅ lua-resty-http 完整模块包已安装"
echo " ✅ 其他常用模块已安装"
echo " ✅ systemd 服务已配置"
echo
log_info "📁 已安装的 HTTP 相关模块:"
find /usr/local/openresty/lualib/resty -name "*http*" 2>/dev/null | sed 's/^/ /' || echo " (模块文件检查失败)"
echo
log_info "🚀 启动命令:"
echo " sudo systemctl start openresty # 启动服务"
echo " sudo systemctl stop openresty # 停止服务"
echo " sudo systemctl restart openresty # 重启服务"
echo " sudo systemctl status openresty # 查看状态"
echo " sudo /usr/local/openresty/bin/openresty -t # 测试配置"
echo " sudo /usr/local/openresty/bin/openresty -s reload # 重新加载配置"
echo
log_info "📚 可用工具:"
echo " /usr/local/openresty/bin/openresty # 主程序"
echo " /usr/local/openresty/bin/opm # 包管理器"
echo " /usr/local/openresty/bin/resty # Lua 解释器"
echo " /usr/local/openresty/bin/restydoc # 文档工具"
echo
log_info "🔍 查看所有可用包:"
if [ "$DISTRO" = "redhat" ]; then
echo " sudo yum --disablerepo=\"*\" --enablerepo=\"openresty\" list"
else
echo " apt list --installed | grep openresty"
fi
echo
log_info "🧪 测试模块使用:"
echo " cd /usr/local/openresty/lualib"
echo " lua -e \"local http = require 'resty.http'; print('HTTP module loaded successfully')\""
echo
log_info "📝 配置文件位置:"
echo " 主配置: /usr/local/openresty/nginx/conf/nginx.conf"
echo " 日志目录: /usr/local/openresty/nginx/logs/"
echo " 模块目录: /usr/local/openresty/lualib/"
echo
echo "=================================================================="
log_info "🎉 OpenResty 完整安装成功!"
log_info "现在可以直接使用 lua-resty-http 模块,不会再出现依赖问题。"
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)
}
}
}
}