2870 字
14 分钟
OpenResty安装和调优
OpenResty安装和调优
系统内核参数优化
安装脚本
#!/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 1fi
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-devfi
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 updatefi
log_info "✅ 软件源配置完成"
# 步骤3:安装 OpenResty 核心log_step "=== 3/8. 安装 OpenResty 核心 ==="
log_info "安装 OpenResty 主程序..."if [ "$PKG_MANAGER" = "yum" ]; then yum install -y openrestyelse apt-get install -y openrestyfi
# 验证安装if [ -f "/usr/local/openresty/bin/openresty" ]; then log_info "✅ OpenResty 核心安装成功" /usr/local/openresty/bin/openresty -velse log_error "OpenResty 核心安装失败" exit 1fi
# 步骤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 "项目解压失败,使用备用安装方式" fielse 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 selfendreturn _MEOF # 创建 http_headers.lua cat > /usr/local/openresty/lualib/resty/http_headers.lua << 'EOF'local _M = { _VERSION = '0.16.1' }function _M.new() return {} endreturn _MEOF 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 -vlog_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 endend
-- 测试核心模块local modules = { "cjson", "resty.http", "resty.http_headers"}
print("开始模块加载测试...")local all_ok = truefor _, mod in ipairs(modules) do if not test_module(mod) then all_ok = false endend
if all_ok then print("\n🎉 所有核心模块测试通过!") os.exit(0)else print("\n⚠️ 部分模块测试失败") os.exit(1)endEOF
# 运行测试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 命令不可用,跳过模块测试" fifi
# 清理测试文件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 PlatformAfter=syslog.target network-online.target remote-fs.target nss-lookup.targetWants=network-online.target
[Service]Type=forkingPIDFile=/usr/local/openresty/nginx/logs/nginx.pidExecStartPre=/usr/local/openresty/bin/openresty -tExecStart=/usr/local/openresty/bin/openrestyExecReload=/bin/kill -s HUP $MAINPIDExecStop=/bin/kill -s QUIT $MAINPIDPrivateTmp=true
[Install]WantedBy=multi-user.targetEOF
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 -tif [ $? -eq 0 ]; then log_info "✅ 配置文件语法正确"else log_warn "配置文件语法有问题,请检查"fi
echoecho "=================================================================="echo " 安装完成总结"echo "=================================================================="echo "完成时间: $(date)"echo
log_info "📋 安装总结:"echo " ✅ 系统识别: $DISTRO ($PKG_MANAGER)"echo " ✅ 冲突处理: 自动替换 curl-minimal"echo " ✅ OpenResty 核心已安装"echo " ✅ lua-resty-http 完整模块包已安装"echo " ✅ systemd 服务已配置"
echolog_info "🚀 常用命令:"echo " 启动: sudo systemctl start openresty"echo " 测试: sudo /usr/local/openresty/bin/openresty -t"echo " 重载: sudo systemctl reload openresty"
echolog_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/