捣鼓了一天,结果发现是宝塔面板编译的lua脚本版本太低。如果不是新服务器不要搞下面的方式,免得影响访问和数据
如果是新服务器可以可以先手动升级 Nginx 的 Lua 模块(适用于无法重装)
1. 下载高版本 ngx_http_lua_module
cd /usr/local/src
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.23.tar.gz
tar -zxvf v0.10.23.tar.gz
2. 重新编译 Nginx(以宝塔 Nginx 为例)
# 停止Nginx
systemctl stop nginx
# 进入宝塔Nginx源码目录(根据实际路径调整)
cd /www/server/nginx/src
# 重新配置(添加Lua模块)
./configure --add-module=/usr/local/src/lua-nginx-module-0.10.23 \
--with-http_ssl_module --with-http_v2_module
# 编译并安装(保留原配置,不删除旧文件)
make && make install
3. 验证模块版本
nginx -V 2>&1 | grep "lua"
# 应显示 ngx_http_lua_module 0.10.23 或更高版本
然后直接上nginx的配置文件
user www www;
worker_processes auto;
error_log /www/wwwlogs/nginx_error.log crit;
pid /www/server/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
stream {
log_format tcp_format '$time_local|$remote_addr|$protocol|$status|$bytes_sent|$bytes_received|$session_time|$upstream_addr|$upstream_bytes_sent|$upstream_bytes_received|$upstream_connect_time';
access_log /www/wwwlogs/tcp-access.log tcp_format;
error_log /www/wwwlogs/tcp-error.log;
include /www/server/panel/vhost/nginx/tcp/*.conf;
}
events {
use epoll;
worker_connections 51200;
multi_accept on;
}
http {
include mime.types;
include proxy.conf; # 包含proxy.conf中的缓存路径定义
lua_package_path "/www/server/nginx/lib/lua/?.lua;;";
# 1. 清理冗余路径,只保留2个核心路径(根据实际环境调整)
lua_package_cpath "/usr/local/lib/lua/5.1/?.so;;";
# 2. 必须加载resty.core(解决resty.http的依赖)
init_by_lua_block {
require "resty.core"
}
# 自定义日志格式(用于缓存统计)
log_format cache_log '$remote_addr [$time_local] "$request" $status '
'$upstream_cache_status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 共享内存定义(必须放在http块内)
lua_shared_dict m3u8_processed_dy1 10m; # 第一个网站的m3u8处理记录
lua_shared_dict m3u8_processed_dy2 10m; # 第二个网站的m3u8处理记录
default_type application/octet-stream;
server_names_hash_bucket_size 512;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 50m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js application/x-mpegURL video/MP2T;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server_tokens off;
access_log off;
server {
listen 888;
server_name phpmyadmin;
index index.html index.htm index.php;
root /www/server/phpmyadmin;
allow 127.0.0.1;
allow ::1;
deny all;
include enable-php.conf;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
}
location ~ .*\.(js|css)?$ {
expires 12h;
}
location ~ /\. {
deny all;
}
access_log /www/wwwlogs/access.log;
}
include /www/server/panel/vhost/nginx/*.conf;
}
网站反向代理配置文件。我的是多个网站,并且反向代理缓存文件分开了的可查看👉宝塔面板反向代理缓存修改地址 如下面的网站的保存缓存文件夹是:/www/server/nginx/proxy_cache_dir_dy1
然后相应网站反向代理配置文件代码是:
# 对应文件:/www/server/panel/vhost/nginx/proxy/dy1.51fxzq.com/xxx_dy1.51fxzq.com.conf
location / {
# 启用缓存日志(便于排查问题)
access_log /www/wwwlogs/dy1_cache.log cache_log;
# 处理m3u8文件(修正后Lua脚本)
location ~* \.m3u8$ {
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 REMOTE-HOST $remote_addr;
proxy_pass https://你的反向代理网址.com; # 第一个网站源站地址
proxy_cache cache_dy1; # 对应proxy.conf中的缓存区域(cache_dy1)
proxy_cache_valid 1h; # m3u8缓存1小时(避免内容更新延迟)
proxy_ignore_headers Cache-Control;
add_header X-Cache "$upstream_cache_status from $server_addr";
# 超时设置(适配长连接和预加载需求)
proxy_read_timeout 300s;
proxy_connect_timeout 300s;
# 修正后的Lua脚本:解析m3u8 + 预加载ts(兼容各类路径格式)
body_filter_by_lua_block {
-- 手动添加模块搜索路径(根据实际路径修改)
package.path = "/usr/local/share/lua/5.1/?.lua;" .. package.path
package.cpath = "/usr/local/lib/lua/5.1/?.so;" .. package.cpath
-- 验证模块是否能加载
local ok, http = pcall(require, "resty.http")
if not ok then
ngx.log(ngx.ERR, "dy1 模块加载失败:", http, " | 路径:", package.path)
return
end
-- 1. 初始化独立共享内存(避免与其他网站冲突)
local dict = ngx.shared.m3u8_processed_dy1
local uri = ngx.var.uri
local processed = dict:get(uri)
if processed then return end -- 已处理过的m3u8直接返回,避免重复预加载
-- 2. 获取m3u8文件内容(处理分块传输场景)
local body = ngx.arg[1]
if not body then return end -- 无内容时退出,避免空指针错误
-- 3. 解析m3u8内容,提取ts文件路径(兼容相对/绝对/带端口路径)
local ts_files = {}
for line in string.gmatch(body, "[^\r\n]+") do
-- 匹配ts行(忽略注释行,过滤非ts内容)
if string.match(line, "%.ts") and not string.match(line, "^#") then
local ts_path = line:gsub("%s+", "") -- 去除路径中的空格,避免404
-- 处理非完整URL的ts路径(拼接完整URL)
if not string.match(ts_path, "^http[s]?://") then
local scheme = ngx.var.scheme -- 获取当前协议(http/https)
local host = ngx.var.host -- 获取当前反向代理域名
-- 处理根路径格式(如:/video/2025/xxx.ts)
if string.match(ts_path, "^/") then
ts_path = scheme .. "://" .. host .. ts_path
else
-- 处理相对路径(如:./xxx.ts 或 xxx.ts),基于当前m3u8路径拼接
local m3u8_dir = ngx.var.uri:match("(.*/)") or "/" -- 提取m3u8所在目录
ts_path = scheme .. "://" .. host .. m3u8_dir .. ts_path
end
end
table.insert(ts_files, ts_path)
end
end
-- 4. 预加载ts文件(增加错误捕获,避免脚本崩溃)
local ok, http = pcall(require, "resty.http")
if not ok then
ngx.log(ngx.ERR, "dy1 Lua依赖缺失:resty.http模块未安装,无法预加载TS")
return
end
local httpc = http.new()
httpc:set_timeout(15000) -- 15秒超时(适配大尺寸ts文件)
local max_concurrent = 3 -- 控制并发数,避免源站压力过大
-- 5. 异步预加载逻辑(用timer避免阻塞主请求)
local function load_ts(index)
if index > #ts_files then return end -- 所有ts加载完成后退出
local ts = ts_files[index]
-- 捕获请求异常,避免单个ts加载失败导致整个脚本崩溃
local ok, res, err = pcall(httpc.request_uri, httpc, ts, {
method = "GET",
headers = {
["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
["Host"] = ngx.var.host,
["Referer"] = ngx.var.http_referer or "" -- 携带Referer,适配防盗链
},
keepalive_timeout = 30000, -- 长连接超时(30秒)
keepalive_pool = 10 -- 连接池大小
})
-- 错误日志记录(便于排查问题)
if not ok then
ngx.log(ngx.ERR, "dy1 TS预加载Lua错误:", ts, " | 错误信息:", res)
elseif err then
ngx.log(ngx.ERR, "dy1 TS预加载网络错误:", ts, " | 错误信息:", err)
elseif res.status < 200 or res.status >= 300 then
ngx.log(ngx.WARN, "dy1 TS预加载状态异常:", ts, " | 状态码:", res.status)
end
-- 递归加载下一个ts(用timer异步执行,不阻塞主请求)
ngx.timer.at(0, load_ts, index + 1)
end
-- 6. 启动预加载(仅首次访问时执行)
if #ts_files > 0 then
load_ts(1)
dict:set(uri, true, 600) -- 标记为已处理,10分钟内不再重复预加载
end
}
}
# 处理ts文件(独立缓存,确保加载速度)
location ~* \.ts$ {
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 REMOTE-HOST $remote_addr;
proxy_pass https://你的反向代理网址.com;
proxy_cache cache_dy1; # 对应cache_dy1缓存区域
proxy_cache_valid 14d; # ts文件缓存14天(内容稳定)
proxy_ignore_headers Cache-Control;
add_header X-Cache "$upstream_cache_status from $server_addr";
# 传输优化(提升ts加载速度)
sendfile on;
tcp_nopush on;
# 超时设置(适配大文件传输)
proxy_read_timeout 60s;
proxy_connect_timeout 30s;
}
# 处理其他媒体文件(图片、字体等,统一缓存策略)
location ~* \.(jpg|png|gif|jpeg|ttf|webp|woff|woff2|ico)$ {
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 REMOTE-HOST $remote_addr;
proxy_pass https://你的反向代理网址.com;
proxy_cache cache_dy1;
proxy_cache_valid 14d;
proxy_ignore_headers Cache-Control;
add_header X-Cache "$upstream_cache_status from $server_addr";
proxy_read_timeout 60s;
proxy_connect_timeout 30s;
}
# 处理其他所有请求(确保网站正常访问,如HTML、JS、API等)
proxy_pass https://你的反向代理网址.com;
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 REMOTE-HOST $remote_addr;
# 基础超时设置(适配常规请求)
proxy_read_timeout 60s;
proxy_connect_timeout 30s;
}














