• 【网页加速】lua redis的二次升级


    之前发过openresty的相关文章,也是用于加速网页速度的,但是上次没有优化好代码,这次整理了下,优化了nginx的配置和lua的代码,感兴趣的话可以看看上篇的文章:
    https://www.cnblogs.com/w1570631036/p/8449373.html

    为了学习,不断的给自己的服务器装东西,又是logstash,又是kafka,导致主站网络负载、cpu消耗过大,再加上tomcat这个本身就特别占用内存的东西,只要稍微刷新一下网站,就能感受到蜗牛般的速度,实在受不了,前段时间给网站加了n多层缓存,依旧没有改观多少,想了想,算了,一直都这么卡,还不如直接将动态的网站直接变成静态网页存储在redis里面,然后关掉tomcat,貌似没有改观多少,但是在xshell里面敲命令没那么卡了,这里,也提出了一种别样的网站加速方法——redis存储静态网页。

    一、总体流程如下

    1.一次请求过来,通过openresty的nginx来访问lua脚本;
    2.读取redis中是否存在该uri对应的静态网页,如果有,则直接返回,否则回源到tomcat,然后将响应的内容保存到redis里面。

    二、nginx的设置

    openresty中自带了nginx,所以只需要配置一下即可,我们最终的目前是拦截所有以html结尾的请求,如果是以其他后缀结尾的,比如do,则可以直接回滚到tomat里面去。
    由于篇幅的关系,只粘贴部分nginx配置,想看全的请转至:mynginxconfig.ngx

        server {
            listen       80;
            # listen       443 ssl;   # ssl
            server_name  www.wenzhihuai.com;
            location  ~ .*.(html)$ {		//拦截所有以html结尾的请求,调用lua脚本
    			...
                charset utf8;
                proxy_pass_request_headers off ;
                # 关闭缓存lua脚本,调试的时候专用
                lua_code_cache off;
                content_by_lua_file /opt/lua/hello.lua;
            }
            location / {		//nginx是按顺序匹配的,如果上面的不符合,那么将回滚tomcat
                default_type    text/html;
                root   html;
                index  index.html index.htm;
    			...
                # websocket
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_pass http://backend;
            }
    

    三、lua脚本

    为了方便key的操作,经过测试,即使uri带有各种字符,比如 ? . html = &等,都是可以直接设置为redis中的key的,所以,不是那么的需要考虑redis的key违反规则,可以直接将uri设置为key。具体流程如下:

    local key = request_uri
    首先,key为请求访问的uri
    local resp, err = red:get(key)
    去redis上查找有没有
    if resp == ngx.null then
        如果没有
        ngx.req.set_header("Accept", "text/html,application/xhtml+xml,application/xml;")
        ngx.req.set_header("Accept-Encoding", "")
        这里,特别需要注意的是,要把头部的信息去掉,这里之前说过。(如果不去掉,就是gzip加密返回,然后再经过一层gzip加密返回给用户,导致用户看到的是gzip压缩过的乱码)
        local targetURL = string.gsub(uri, "html", "do")
       	这里讲html替换为do,即:不拦截*.do的请求,其可以直接访问tomcat
        local respp = ngx.location.capture(targetURL, { method = ngx.HTTP_GET, args = uri_args })
        开始回源到tomcat
    	red:set(key, respp.body)
    	将uri(key)和响应的内容设到redis里面去
        red:expire(key, 600)
    	lua redis并没有提供在set的时候同时设置过期时间,所以,额外加一行设置过期时间
        ngx.print(respp.body)
    	将响应的内容输出给用户
        return
    end
    ngx.print(resp)
    
    
    

    四、测试

    进行一次测试,以访问http://www.wenzhihuai.com/jaowejoifjefoijoifaew.html 为例,我的网站并没有设置这个uri,所以,访问的时候,会统一调到错误页面,之后,会在redis中看到有这条记录:

    该地址已经成功被缓存到redis里面去,点击其他页面,可以看到,只要是点击的页面,都被缓存到redis里面去了。总体来说,如果不设置过期时间,可以把整个网页静态化缓存到redis里面,甚至是可以关闭tomcat了,但是这种做法只适用于万年不变的页面,至于用于企业的话,,,,

    后记:
    其实我有个疑问,我的代码里,并没有设置lua断开redis的连接,不知道会不会有影响,而且它这个是指每次请求过来,都需要重新连接redis么?光是TCP三次握手就耗时不少啊,不知道怎么优化这些信息。

    全部代码如下:

    local redis = require "resty.redis"
    local red = redis:new()
    local request_uri = ngx.var.request_uri
    local ngx_log = ngx.log
    local ngx_ERR = ngx.ERR
    
    local function close_redis(red)
        if not red then
            return
        end
        local pool_max_idle_time = 10000
        local pool_size = 100
        red:set("pool_size", pool_size)
        local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
        if not ok then
            ngx_log(ngx_ERR, "set redis keepalive error : ", err)
        end
    end
    
    local uri = ngx.var.uri
    
    red:set_timeout(1000)
    red:connect("119.23.46.71", 6340)
    red:auth("root")
    local uri_args = ngx.req.get_uri_args()
    
    local key = request_uri
    local resp, err = red:get(key)
    
    if resp == ngx.null then
        ngx.req.set_header("Accept", "text/html,application/xhtml+xml,application/xml;")
        ngx.req.set_header("Accept-Encoding", "")
        local targetURL = string.gsub(uri, "html", "do")
        local respp = ngx.location.capture(targetURL, { method = ngx.HTTP_GET, args = uri_args })
        red:set(key, respp.body)
        red:expire(key, 600)
        ngx.print(respp.body)
        return
    end
    ngx.print(resp)
    close_redis(red)
    
    
    
  • 相关阅读:
    进程隐藏类
    MFC中一些使用的方法
    c++/vc++的一些学习方法
    随意更改桌面壁纸
    Winsock异步模型之(事件通知模型 WSAAsyncSelect)
    开发外挂的一些原理
    ios 图片
    得到cell的坐标
    取出字符串中的空格
    ios 获取当前的日期,年月日
  • 原文地址:https://www.cnblogs.com/w1570631036/p/9226519.html
Copyright © 2020-2023  润新知