一号优惠经验分享网
51福利网的各种薅羊毛福利经验笔记

nginx反向代理自动预加载ts文件需借助 Lua 脚本

捣鼓了一天,结果发现是宝塔面板编译的lua脚本版本太低。如果不是新服务器不要搞下面的方式,免得影响访问和数据

如果是新服务器可以可以先手动升级 Nginx 的 Lua 模块(适用于无法重装)

51福利网

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;
}

一号优惠 · 51福利网薅羊毛福利具有时效性,如已失效,请留言
文章名称:《nginx反向代理自动预加载ts文件需借助 Lua 脚本》-一号优惠 · 51福利网
免责申明:本站所有活动信息均来自网络,如有失效、违规、不实或侵权,请联系我们删除。谢谢

评论 抢沙发

一号优惠经验分享网最新最全薅羊毛,现金红包线报网

一号优惠经验分享网提供每日最新内部优惠,薅羊毛活动,现金红包领取,免费福利和网赚福利手机赚钱线报,打造中国最受欢迎的网赚信息发布平台!51福利网

51联盟线报群赚钱·合作·帮助

登录

找回密码

注册