【網頁加速】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)
【網頁加速】lua redis的二次升級