以前發過openresty的相關文章,也是用於加速網頁速度的,可是上次沒有優化好代碼,此次整理了下,優化了nginx的配置和lua的代碼,感興趣的話能夠看看上篇的文章:
http://www.javashuo.com/article/p-miumizmh-dk.htmlhtml
爲了學習,不斷的給本身的服務器裝東西,又是logstash,又是kafka,致使主站網絡負載、cpu消耗過大,再加上tomcat這個自己就特別佔用內存的東西,只要稍微刷新一下網站,就能感覺到蝸牛般的速度,實在受不了,前段時間給網站加了n多層緩存,依舊沒有改觀多少,想了想,算了,一直都這麼卡,還不如直接將動態的網站直接變成靜態網頁存儲在redis裏面,而後關掉tomcat,貌似沒有改觀多少,可是在xshell裏面敲命令沒那麼卡了,這裏,也提出了一種別樣的網站加速方法——redis存儲靜態網頁。
nginx
1.一次請求過來,經過openresty的nginx來訪問lua腳本;
2.讀取redis中是否存在該uri對應的靜態網頁,若是有,則直接返回,不然回源到tomcat,而後將響應的內容保存到redis裏面。git
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; }
爲了方便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)
進行一次測試,以訪問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)