【網頁加速】lua redis的二次升級

以前發過openresty的相關文章,也是用於加速網頁速度的,可是上次沒有優化好代碼,此次整理了下,優化了nginx的配置和lua的代碼,感興趣的話能夠看看上篇的文章:
http://www.javashuo.com/article/p-miumizmh-dk.htmlhtml

爲了學習,不斷的給本身的服務器裝東西,又是logstash,又是kafka,致使主站網絡負載、cpu消耗過大,再加上tomcat這個自己就特別佔用內存的東西,只要稍微刷新一下網站,就能感覺到蝸牛般的速度,實在受不了,前段時間給網站加了n多層緩存,依舊沒有改觀多少,想了想,算了,一直都這麼卡,還不如直接將動態的網站直接變成靜態網頁存儲在redis裏面,而後關掉tomcat,貌似沒有改觀多少,可是在xshell裏面敲命令沒那麼卡了,這裏,也提出了一種別樣的網站加速方法——redis存儲靜態網頁。
nginx

1、整體流程以下

1.一次請求過來,經過openresty的nginx來訪問lua腳本;
2.讀取redis中是否存在該uri對應的靜態網頁,若是有,則直接返回,不然回源到tomcat,而後將響應的內容保存到redis裏面。git

2、nginx的設置

openresty中自帶了nginx,因此只須要配置一下便可,咱們最終的目前是攔截全部以html結尾的請求,若是是以其餘後綴結尾的,好比do,則能夠直接回滾到tomat裏面去。
因爲篇幅的關係,只粘貼部分nginx配置,想看全的請轉至:mynginxconfig.ngxgithub

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

3、lua腳本

爲了方便key的操做,通過測試,即便uri帶有各類字符,好比 ? . html = &等,都是能夠直接設置爲redis中的key的,因此,不是那麼的須要考慮redis的key違反規則,能夠直接將uri設置爲key。具體流程以下:web

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)

4、測試

進行一次測試,以訪問http://www.wenzhihuai.com/jaowejoifjefoijoifaew.html 爲例,個人網站並無設置這個uri,因此,訪問的時候,會統一調到錯誤頁面,以後,會在redis中看到有這條記錄:redis

該地址已經成功被緩存到redis裏面去,點擊其餘頁面,能夠看到,只要是點擊的頁面,都被緩存到redis裏面去了。整體來講,若是不設置過時時間,能夠把整個網頁靜態化緩存到redis裏面,甚至是能夠關閉tomcat了,可是這種作法只適用於萬年不變的頁面,至於用於企業的話,,,,shell

後記:
其實我有個疑問,個人代碼裏,並無設置lua斷開redis的鏈接,不知道會不會有影響,並且它這個是指每次請求過來,都須要從新鏈接redis麼?光是TCP三次握手就耗時很多啊,不知道怎麼優化這些信息。
緩存

所有代碼以下:tomcat

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)
相關文章
相關標籤/搜索