Lua 业务 脚本

Lua 脚本

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;
    gzip_min_length 1k;     #增加
    gzip_buffers 4 16k;     #增加
    gzip_http_version 1.1;     #增加
    gzip_comp_level 2;         #增加
    gzip_types text/plain application/x-javascript text/css application/xml  text/javascript; #增加
    gzip_vary off;         #增加

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;
        charset utf-8;
        # dns 解析
        resolver 8.8.8.8 114.114.114.114 valid=3600s;

        # access_log  logs/host.access.log  main;
        
        location = /favicon.ico {            
            root html/peixun86;
        }
        
        location  /peixun/clearcache {            
            access_log  logs/clearcache.access.log  main;
            # 这个配置很重要
            default_type text/html;
            # set $domain $host 
            proxy_set_header  X-real-ip $remote_addr; #直接获取客户端IP
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;#通过代理服务器获取客户端IP
            # 只会警告,可以忽略,但是线上一定为on
            lua_code_cache on;
            content_by_lua_file conf/lua/clearcache_work.lua;
        }

        location / {
            access_log  logs/root.access.log  main;
            # 这个配置很重要
            default_type text/html;
            # set $domain $host 
            proxy_set_header  X-real-ip $remote_addr; #直接获取客户端IP
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;#通过代理服务器获取客户端IP
            # 只会警告,可以忽略,但是线上一定为on
            lua_code_cache on;
            content_by_lua_file conf/lua/union_lable_work.lua;

        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}
nginx
local function local_print(str)  
    local dbg = io.open("conf/lua/logs/output.txt", "a+")
    local str = str or ""
    if dbg then
        dbg:write(str..'\n')
        dbg:close()
    end
end

local template = require("resty.template")
local redis = require("resty.redis")
local mysql = require("resty.mysql")



local context = {
    title = "测试",
    name = "张三",
    description = "<script>alert(1);</script>",
    script = "alert(1)",
    age = 20,
    hobby = {"电影", "音乐", "阅读"},
    -- score = {"语文" = 90, "数学" = 80, "英语" = 70},
    score2 = {
      {name = "语文", score = 901},
      {name = "数学", score = 810},
      {name = "英语", score = 710},
    },
    file = 'xiaowu'
  }
  


-- 关闭redis链接
local function close_redes( red )
    if not red then
      return
    end
    local ok, err = red:close()
    if not ok then
        local_print("close redis error:" .. err)
    end
end


-- 创建实例
local red = redis:new()
-- 设置超时(毫秒)
red:set_timeout(2000)
-- 建立连接
local ip = "192.168.10.10"
local port = 7000
local ok, err = red:connect(ip, port)
    if not ok then
        return
    end
-- 没有密码不需要写
-- local res, err = red:auth("")
-- if not res then
--     local_print("connect to redis error : " .. err)
--     return
-- end

-- 调用api进行操作
res, err = red:set("msg", "hello world")
if not res then
    local_print("set msg error : " .. err)
end

local resp, err = red:get("msg")
if not resp then
    local_print("get msg erro:" .. err)
else
    context.title = resp
end


close_redes(red)

---------------------------------------------------------------------------------------
local function close_db( db )
    if not db then
      return
    end
    db:close()
  end
  
  
  -- 创建实例
  local db, err = mysql:new()
  if not db then
    local_print("new  mysql error:" .. err)
    return
  end
  -- 设置超时时间(毫秒)
  db:set_timeout(5000)
  
  local props = {
    host = "192.168.10.5",
    port = 3306,
    database = "union",
    user = "rshy",
    password = "123456"
  }
  
  local res, err, errno, sqlstate = db:connect(props)
  
  if not res then
    local_print("connect to mysql error : " .. err, " , errno : " .. errno, " , sqlstate : " .. sqlstate)
    return close_db(db)
  else
    local select_sql = "select teacherid from teacher limit 2"
    res, err, errno, sqlstate = db:query(select_sql)
    if not res then
        local_print("select error : " .. err, " , errno : " .. errno, " , sqlstate : " .. sqlstate)
        return close_db(db)
    else
        for k, v in pairs(res) do
            local_print(k .. v.teacherid)
        end
    end

  end
---------------------------------------------------------------------------------------


template.render("t1.html", context)
测试

 

local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
        ngx.say("failed to connect: ", err)
        return
end
--密码和选择的桶
red:auth(password)
red:select(18)
ngx.say("set result: ", ok)
local res, err = red:get(download.token.b17efb43-292e-4cc9-ac5d-0b46bce059c5")
if not res then
        ngx.say("failed to get download.token.b17efb43-292e-4cc9-ac5d-0b46bce059c5: ", err)
        return
end
if res == ngx.null then
        ngx.say("download.token.b17efb43-292e-4cc9-ac5d-0b46bce059c5 not found.")
        return
end
ngx.say("download.token.b17efb43-292e-4cc9-ac5d-0b46bce059c5: ", res)
redis

 

-- 区分设备
local function get_device()
    -- 获取请求头信息
    local headers=ngx.req.get_headers()
    -- 获取ua
    local ua = headers['user-agent'] or ''
    local mobel_list = {'mobile', 'android', 'webos', 'iphone', 'ipod', 'blackberry'}
    
    for _, k in ipairs(mobel_list) do
        p, _=string.find(string.lower( ua ), k)
        if p then
            return "wap"
        end
    end
    return "pc"
end

-- 判断文件是否存在
local function file_exists(path)
    local file = io.open(path, "rb")
    if file then file:close() end
    return file ~= nil
end

-- 字符串分割
local function Split(str, sep)
    local sep, fields = sep or "/", {}
    local pattern = string.format("([^%s]+)", sep)
    str:gsub(pattern, function (c) fields[#fields + 1] = c end)
    return fields
end

-- 判断结尾
function string.ends(String,End)
    return End=='' or string.sub(String,-string.len(End))==End
end

-- 构建文件路径
local function get_file_path(url_path, host, device)
    local root_path = '/html/' .. host .. '/' .. device
    
    local end_path = string.ends(url_path, '/')
    if end_path then
        url_path = string.sub(url_path, 1, -2)
        url_path = root_path .. url_path .. '.txt'
        return url_path
    else
        url_path = root_path .. url_path .. '.txt'
        return url_path
    end
end

-- 字符串分割
local function Split(str, sep)
    local sep, fields = sep or "/", {}
    local pattern = string.format("([^%s]+)", sep)
    str:gsub(pattern, function (c) fields[#fields + 1] = c end)
    return fields
end

-- 去除空格
function trim(s) 
    return (string.gsub(s, "^%s*(.-)%s*$", "%1")) 
end

-- 文件保存
local function file_save(file_path, res)
    local file_path_temp = file_path
    local file_path_temp = Split(file_path_temp, "/")
    
    table.remove(file_path_temp)
    
    local concatret = table.concat(file_path_temp, "/")
    local concatret = '/' .. concatret
    
    ngx.say("<!--request-->")
    
    
    -- /html/tingclass/pc/getjarname/xuexi/wiayu/0-1-4.tx
    
    os.execute(string.format("mkdir -p  %s", concatret))
    
    File = io.open(file_path, 'w')
    File:write(res)
    File:close()
    
end

-- 发送请求获取数据
http = require("resty.http")

local function get_replace_templte(union_id, url_path, host, host_ip, device)
    
    -- 发送请求
    local httpc = http.new()
    timeout = 3000
    httpc:set_timeout(timeout)
    local url = "http://" .. host_ip
    local resStr --响应结果
    local res, err = httpc:request_uri(url, {
        method = "GET",
        path = string.format( "/label?aId=%s&deviceType=%s&url=%s",union_id, device, url_path),
        --args = str,
        --body = str,
        headers = {
            ["Content-Type"] = "text/html; charset=utf-8",
            ["HOST"] = host,
        }
    })
    
    
    if res.status ~= 200 then
        ngx.say(string.format("<!--error code: %s-->", res.status))
        -- ngx.exit(res.status)
        return false
    else
        --请求之后,状态码
        return res.body
    end
end

-- 替换数据
local function replace_with(union_id, url_path, body, host, host_ip, device)
    -- 获取替换模板
    local temp = get_replace_templte(union_id, url_path, host, host_ip, device)
    -- local temp = '<!--luaLabel-->' .. '替换了哦。。'
    
    -- "<!--luaLabel-->"
    if temp then
        ngx.say("<!--replace-->")
        local now_time = os.date("%Y-%m-%d-%H-%M-%S", os.time())
        temp = "<!--replaceStart-->" .. temp .. "<!--replaceEnd-->"  .. "<!--luaLabelRiseTimeStart[" .. now_time .. "]luaLabelRiseTimeEnd-->"
        local res_body = string.gsub(body, "<!%-%-luaLabel%-%->", temp)
        return res_body
    else
        ngx.say("<!--not replace-->")
        return false
    end
end

-- 发送请求 
local function send_request(union_id, url_path, host, host_ip, res_exist, device, file_path)
    -- 发送请求
    local httpc = http.new()
    -- http://www.tingclass.net/
    local url = "http://" .. host_ip .. ngx.var.uri
    local resStr --响应结果
    local res, err = httpc:request_uri(url, {
        method = "GET",
        --args = str,
        --body = str,
        headers = {
            ["Content-Type"] = "text/html; charset=utf-8",
            ["HOST"] = host,
        }
    })

    if not res then
        ngx.exit(res.status)
    else
        if res.status == 200 then
            --请求之后,状态码
            ngx.status = res.status
            -- 这里进行修改操作
            -- res.body = 修改后数据
            res_body = replace_with(union_id, url_path, res.body, host, host_ip, device)
            if res_body then
                -- 修改完将数据存入文件
                file_save(file_path, res_body)
                return res_body
            else
                file_save(file_path, res.body)
                return res.body
            end
        else
            ngx.exit(res.status)
        end
    end
end

-- 根据时间清理缓存
local function del_cache(body, union_id, url_path, host, host_ip, res_exist, device, file_path)
    local res = string.match(tostring(body), 'luaLabelRiseTimeStart%[(.*)%]luaLabelRiseTimeEnd')
    if res then
        local  del_cache_time = 4 * 60 * 60
        ngx.say((string.format("<!--res_body: %s-->", res)))
        local data_split_table = Split(res, '-')
        local year_t, month_t, day_t, hour_t, minute_t, second_t = data_split_table[1], data_split_table[2], data_split_table[3], data_split_table[4], data_split_table[5], data_split_table[6] 
        -- ngx.say(year_t, month_t, day_t, hour_t, minute_t, second_t)
        local now_time = os.time()
        local old_time = os.time({day=day_t, month=month_t, year=year_t, hour=hour_t, min=minute_t, sec=second_t})
        if now_time - old_time >= del_cache_time then
            ngx.say("<!--del_cache-->")
            -- 删除进行文章改写
            local res_body = send_request(union_id, url_path, host, host_ip, res_exist, device, file_path)
            return res_body
        else
            return body
        end
    else
        return body
    end
end

-- 根据文件是否存在进行结果返回
local function get_body(union_id, url_path, host, host_ip, res_exist, device, file_path)
    -- 文件存在直接返回结果
    if res_exist then
        ngx.say("<!--file-->")
        local f = io.open(file_path)
        local body = f:read("*a")
        f:close()
        -- 根据换取时间进行判断缓存是否需要清除
        local res_body = del_cache(body, union_id, url_path, host, host_ip, res_exist, device, file_path)
        return res_body
    -- 不存在发送请求获取结果
    else
        local body = send_request(union_id, url_path, host, host_ip, res_exist, device, file_path)
        return body
    end
end

-- 从上游服务器获取 ip_port
local upstream = require "ngx.upstream"

local function getUpstreamIps()
    local us = upstream.get_primary_peers('lua.ip.port')
    local ips = {}
    for _, u in ipairs(us) do
        table.insert(ips, u["name"])
    end
    return ips

end


local function getFrontIp()
    local ips = getUpstreamIps()

    local ramdom = math.random(0, #ips);
    return ips[ramdom]
end


local function main()
  -- 第一步,业务分类  (区分 WAP/PC)
  local device = get_device()
  
  -- 第二步,获取文件路径
  local host = ngx.var.http_host
  local url_path = ngx.var.uri
  local file_path = get_file_path(url_path, host, device)
  
  -- 第三步, 判断文件是否存在
  local res_exist = file_exists(file_path)
  
  -- 第四步,返回结果
  ngx.say(string.format("<!--host: %s-->", host))
  local host_ip = getFrontIp()
  local union_id = 23
  local body = get_body(union_id, url_path, host, host_ip, res_exist, device, file_path)
    -- 文件存在直接返回结果
    -- 不存在发送请求获取结果
  ngx.say(body)
end

main()
-- 区分设备
local function get_device()
    -- 获取请求头信息
    local headers=ngx.req.get_headers()
    -- 获取ua
    local ua = headers['user-agent'] or ''
    local mobel_list = {'mobile', 'android', 'webos', 'iphone', 'ipod', 'blackberry'}
    
    for _, k in ipairs(mobel_list) do
        p, _=string.find(string.lower( ua ), k)
        if p then
            return "wap"
        end
    end
    return "pc"
end

-- 判断结尾
function string.ends(String,End)
    return End=='' or string.sub(String,-string.len(End))==End
end

-- 构建文件路径
local function get_file_path(url_path, host, device)
    local root_path = '/html/' .. host .. '/' .. device
    
    local end_path = string.ends(url_path, '/')
    if end_path then
        url_path = string.sub(url_path, 1, -2)
        url_path = root_path .. url_path .. '.txt'
        return url_path
    else
        url_path = root_path .. url_path .. '.txt'
        return url_path
    end
end

-- 判断文件是否存在
local function file_exists(path)
    local file = io.open(path, "rb")
    if file then file:close() end
    return file ~= nil
end

-- 入口函数
local function main()
  -- (区分 WAP/PC)
  local device = get_device()
  
  -- 获取url - path
  local url_path = ngx.var.uri
  local host = ngx.var.http_host
  
  --local host = ngx.var.http_host
  local file_path = get_file_path(url_path, host, device)
  ngx.say(file_path)
  ngx.say('<br>')
  local file_path = string.gsub(file_path, "/clearcache", "")
  ngx.say(file_path)
  
  -- 判断文件是否存在
  local res_exist = file_exists(file_path)
  
  if res_exist then
    os.remove( file_path )
    ngx.say('<h1>删除成功</h1>')
  else
    ngx.say('<h1>没有缓存,不需要删除</h1>')
  end
  
  
  -- 
  --host_ = "www.tingclass.net"
  --host_ip_ = "115.159.89.139"
  --host__ = "tingclass.test.com"
  --host_ip__ = "192.168.0.146:8081"
  -- 47.93.220.246
  --local host = ngx.var.http_host --"www.tingclass.net"

end

main()

 

posted @ 2020-06-10 18:51  小学弟-  阅读(309)  评论(0)    收藏  举报