Skip to content

Instantly share code, notes, and snippets.

@isage
Created May 30, 2015 02:24
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save isage/509d99cf4def36014f5c to your computer and use it in GitHub Desktop.
Save isage/509d99cf4def36014f5c to your computer and use it in GitHub Desktop.
openresty-redis-example
user nginx;
worker_processes 2;
error_log logs/error.log;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
init_by_lua '
json = require "cjson";
redis = require "resty.redis"
';
server {
listen 8080;
server_name localhost;
#charset koi8-r;
access_log logs/host.access.log main;
gzip on;
root /var/www/wduy.ru/www;
expires max;
set $redis_host "192.168.2.104";
set $redis_port "6379";
set $redis_pass "nightmaremoon";
location /
{
root /var/www/wduy.ru/www/;
}
location = /scores
{
content_by_lua '
local red = redis:new()
local ok, err = red:connect(ngx.var.redis_host, ngx.var.redis_port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ok, err = red:auth(ngx.var.redis_pass)
if not ok then
ngx.say("failed to auth: ", err)
return
end
local keys, err = red:keys("*")
ngx.header.content_type = "text/plain"
local scores = {}
for i, key in ipairs(keys) do
scores[key] = red:get(key)
end
ngx.say(json.encode(scores))
';
}
location ~* ^/scores/max/(?<key>.*)$
{
content_by_lua '
ngx.header.content_type = "text/plain"
local red = redis:new()
local ok, err = red:connect(ngx.var.redis_host, ngx.var.redis_port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ok, err = red:auth(ngx.var.redis_pass)
if not ok then
ngx.say("failed to auth: ", err)
return
end
local max = 0
for key in string.gmatch(ngx.var.key, \'([^,]+)\') do
local res = ngx.location.capture("/scores/" .. key)
data = json.decode(res.body)
if tonumber(data.value) > max then
max = tonumber(data.value)
end
end
ngx.say(json.encode({ max = max }))
';
}
location ~* ^/scores/(?<key>.*)$
{
lua_need_request_body on;
content_by_lua '
local red = redis:new()
local ok, err = red:connect(ngx.var.redis_host, ngx.var.redis_port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ok, err = red:auth(ngx.var.redis_pass)
if not ok then
ngx.say("failed to auth: ", err)
return
end
local method_name = ngx.req.get_method()
if method_name == "GET" then
local val, err = red:get("user:score:" .. ngx.var.key)
ngx.header.content_type = "text/plain"
ngx.say(json.encode({value = val}))
elseif method_name == "PUT" then
data = json.decode(ngx.req.get_body_data())
red:set("user:score:" .. ngx.var.key, data.value)
ngx.req.set_method(ngx.HTTP_GET)
ngx.exec("/scores/" .. ngx.var.key)
elseif method_name == "DELETE" then
red:delete("user:score:" .. ngx.var.key)
ngx.say(json.encode({result = "success"}))
end
';
}
location = /scores/max
{
content_by_lua '
ngx.header.content_type = "text/plain"
local red = redis:new()
local ok, err = red:connect(ngx.var.redis_host, ngx.var.redis_port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ok, err = red:auth(ngx.var.redis_pass)
if not ok then
ngx.say("failed to auth: ", err)
return
end
local sha, err = red:script("load","local max = 0; local keys = redis.call(\'keys\', \'user:score:*\'); for i, key in ipairs(keys) do local value = tonumber(redis.call(\'get\', key)); if value > max then max = value end end; return max")
if not sha then
ngx.say("failed to load: ", err)
return
end
local val, err = red:evalsha(sha, 0)
if not val then
ngx.say("failed to eval: ", err)
return
end
ngx.say(json.encode({ max = val }))
';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment