Last active
October 17, 2015 06:40
-
-
Save wonderbeyond/498c6884e2370eae7ca1 to your computer and use it in GitHub Desktop.
基于 Nginx+Lua+Redis(http://openresty.org/) 的页面缓存配置案例
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| server { | |
| listen 80; | |
| server_name localhost; | |
| location ~ ^/update(/.*)$ { | |
| proxy_pass http://127.0.0.1:8000$1$is_args$args; | |
| } | |
| location /api/ { | |
| # set expire timeout, in seconds | |
| set $cache_timeout 3600; | |
| content_by_lua ' | |
| -- TODO: support vary on specified header | |
| local cjson = require "cjson" | |
| local update_url = "/update" .. ngx.var.request_uri | |
| local redis = require "resty.redis" | |
| local red = redis:new() | |
| red:set_timeout(1000) | |
| local ok, err = red:connect("127.0.0.1", 6379) | |
| if not ok then | |
| ngx.say("Failed to connect: ", err) | |
| return | |
| end | |
| -- try get content from redis | |
| local key = ngx.var.request_uri | |
| local cache, err = red:hmget(key, "header", "body") | |
| if not cache then | |
| -- fetch error | |
| ngx.say("Failed to get ", key , err) | |
| return | |
| end | |
| if cache ~= ngx.null and cache[1] ~= ngx.null then | |
| -- hit cache | |
| ngx.header.X_From_Page_Cache = "true" | |
| local header, body = cjson.decode(cache[1]), cache[2] | |
| ngx.header["Content-Type"] = header["Content-Type"] | |
| ngx.say(body) | |
| ngx.eof() | |
| else | |
| -- fetch from upstream | |
| ngx.log(ngx.INFO, key, " not exists") | |
| local res = ngx.location.capture(update_url) | |
| -- response to client & update data to cache | |
| ngx.status = res.status | |
| for k, v in pairs(res.header) do | |
| ngx.header[k] = v | |
| end | |
| ngx.say(res.body) | |
| ngx.eof() | |
| if res.status == 200 then | |
| -- NOTE: json encode&decode leads to much performance loss | |
| red:hmset(key, "header", cjson.encode(res.header), "body", res.body) | |
| local cache_timeout = ngx.var.cache_timeout | |
| red:expire(key, cache_timeout ~= nil and cache_timeout or 60*60) | |
| end | |
| end | |
| -- Puts the connection into connection pool | |
| -- This gets about 30% performance boost(tested by wonder) | |
| local ok, err = red:set_keepalive(1000*60*60, 10) | |
| if not ok then | |
| ngx.log(ngx.EMERG, "Faied to keepalive", err) | |
| end | |
| '; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment