美文网首页
响应静态化放到Nginx上

响应静态化放到Nginx上

作者: 昵称个P | 来源:发表于2020-06-25 17:22 被阅读0次

    目前这部分还未投产,也只做了nginx读取静态化文件部分,元数据修改后变更静态化文件还未实现。性能和之前相比,需要压测做验证。

    1. 首先修改nginx.conf
    # 先把工作进程数改到最大,和CPU核数保持一致。
    worker_processes 8;
    server {
      # 打开lua代码缓存参数,http和https两个server域都需要加入该参数
      lua_code_cache on;
    }
    
    1. 将lua脚本放到nginx的conf目录下
    2. 将custom.conf文件复制到nginx.conf平级目录,custom.conf文件中的lua脚本需要写绝对路径。
    3. 在nginx.conf文件的server域中include custom.conf文件,http和https两个server域都需要加入,位置在所有location第一个。
    include custom.conf;
    

    另外还需要一些其他配置,保证环境

    • 添加json模块
    • 引入lua模块文件,在nginx.conf的http域中添加下面两句
    lua_package_path "/opt/nginx/conf/?.lua;/opt/nginx/conf/lualib/?;/opt/nginx/conf/lualib/resty/?.lua;;";
    lua_package_cpath "/opt/nginx/lualib/?.so;;";
    

    附录

    custom.conf

    set $upsname '_';
    set $suffix '_';
    
    -- 用lua脚本处理指定的请求
    location ^~ /temp/test.do {
        content_by_lua_file /opt/nginx/conf/custom/test.lua;
    }
    
    -- 通用转发
    location @default {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $http_x_forwarded_for;
        proxy_pass  http://$upsname/$suffix;
    }
    

    test.lua

    请求处理lua脚本,逻辑:如果不是POST请求,不是缓存能处理的参数,处理异常或者没有对应的缓存,则转发到upstream处理,反之,拼接参数做成key,从缓存中获取value返回。

    -- 引入cjson,data,base模块
    local json = require 'cjson'
    local data = require 'data'
    local base = require 'base'
    local prefix = 'appbanner_'
    
    function main()
        -- 获取request method
        local request_method = ngx.var.request_method
    
        -- 只处理Post请求
        if request_method == 'POST' then
            -- 获取content-type请求头
            local headers = ngx.req.get_headers()
            local contentType = headers['content-type']
            -- 如果没有指定content-type,则转发给upstream处理
            if type(contentType) == 'nil' then
                base.forward()
                return
            end
    
            -- 读取body
            ngx.req.read_body()
            local request_data
            if contentType == 'application/json' then
                -- 如果是json参数,则反序列化成对象
                local args = ngx.req.get_body_data()
                request_data = json.decode(args)
            elseif contentType == 'application/x-www-form-urlencoded' then
                -- 如果是表单提交,则按实际情况获取
                local args = ngx.req.get_post_args()
                local jsonData = args['jsonData']
                jsonData = base.urlDecode(jsonData)
                request_data = json.decode(jsonData)
                request_data = request_data['data']
            else
                -- 如果是其他content-type,转发给upstream处理
                base.forward()
            end
    
            -- 读取body里业务参数
            local appVersion = request_data['test1']
            local testFlag = request_data['test2']
             
            -- 如果是缓存无法处理的参数,则转发给upstream
            if testFlag == '1' or appVersion < '2.8.0' then
                ngx.log(ngx.ERR, 'forward to zag because of test flag or app version is less than 2.8.0')
                base.forward()
           else
                ngx.log(ngx.ERR, 'try to get data from data.lua')
                -- 读取参数,拼接缓存的 key,根据不同参数
                local dataKey = prefix .. appVersion .. testFlag
                dataKey = string.gsub(dataKey , '%.', '_')
                -- 从data.lua中获取缓存
                local cacheData = data[dataKey]
    
                -- 如果没有缓存,转发给upstream
                if type(cacheData) == 'nil' then
                    base.forward()
                else
                    -- 设置响应头,发送给客户端
                    ngx.log(ngx.ERR, 'return response using lua data, from ', dataKey)
                    ngx.header.content_type = 'text/html;charset=UTF-8'
                    ngx.header['access-control-allow-headers'] =
                        'X-Request-With,content_type,token,timestamp,x-header-sign,random,x-app-version,x-h5-version'
                    ngx.header['access-control-allow-methods'] = 'GET,PUT,OPTIONS,POST'
                    ngx.header['access-control-allow-origin'] = '*'
                    local response_data = '{"code":"200","msg":"操作成功","data":' .. cacheData .. '}'
                    ngx.say(response_data)
                end
            end
        else
            ngx.say('error:request method not support')
        end
    end
    
    local status, err = pcall(main)
    
    if status then
        ngx.log(ngx.ERR, 'ok')
    else
        -- 如果异常,转发给upstream
        ngx.log(ngx.ERR, err)
        base.forward()
    end
    

    data.lua

    数据lua脚本

    local _M = {}
    
    -- 类似Map
    _M.service_12_8_0 = [[{"data":"212312312312"}]]
    

    base.lua

    常用方法的lua脚本

    local _M = {}
    
    running_cluster = '@default'
    -- upstream name
    upsname = 'ng_zuul'
    
    _M.running_cluster = running_cluster
    _M.upsname = upsname
    
    -- 获取url域名后的部分
    local function getUrlSuffix(request_uri)
        return string.gsub(request_uri, '/(.*)', '%1')
    end
    
    -- 请求转发到upstream
    function _M.forward()
        local request_uri = ngx.var.request_uri
        local suffix = getUrlSuffix(request_uri)
        ngx.var.upsname = upsname
        ngx.var.suffix = suffix
        ngx.exec(running_cluster)
        return
    end
    
    -- url encode字符
    function _M.urlEncode(s)
        s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)  
       return string.gsub(s, " ", "+")
    end
    
    -- url decode字符
    function _M.urlDecode(s)
       s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)  
       return s
    end
    
    return  _M
    

    相关文章

      网友评论

          本文标题:响应静态化放到Nginx上

          本文链接:https://www.haomeiwen.com/subject/zibsfktx.html