OpenResty 这里就不介绍了,可以阅读 OpenResty(nginx)操作mysql的初步应用 或 参阅 http://openresty.org

要想在nginx里访问redis,需要HttpRedis模块 或 HttpRedis2Module模块 或 HttpLuaModule模块的lua-resty-redis库。HttpRedis模块提供的指令少,功能单一,适合做简单缓存,可能以后会扩展。HttpRedis2Module模块比前面的HttpRedis模块操作更灵活,功能更强大。最后一个提供了一个操作redis的接口,可根据自己的情况作一些逻辑处理,类似php开发中的各种扩展,需要自己开发逻辑。如果在安装OpenResty时没有显示的禁用前两个模块,默认是启用的,对于第三个模块可以使用--with-luajit,开启luajit支持,lua-resty-redis库默认是启用的。

方案一、使用HttpRedis
1、配置nginx.conf
worker_processes 1;
error_log logs/error.log debug;
events {
        worker_connections 1024;
}
http {
        include mime.types;
        default_type application/octet-stream;
        sendfile on;
        keepalive_timeout 65;
        server {
                listen 80;
                server_name localhost;
                root html;
                index index.html index.htm;
                location / {
                        default_type text/html;
                        
set $redis_key $uri;
                        redis_pass 127.0.0.1:6379;
                        error_page 404 = @fetch;

                }
                location @fetch {
                        root html;
                }

        }
}

2、测试配置并重启nginx
3、测试
[root@vm5 conf]# curl -i localhost/common.js
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Wed, 20 Feb 2013 19:14:57 GMT
Content-Type: application/x-javascript
Content-Length: 23
Last-Modified: Wed, 20 Feb 2013 19:08:50 GMT
Connection: keep-alive
Accept-Ranges: bytes

// this a test js file
说明:现在redis缓存里是空的,什么都没存,所以404了,转向命名location @fetch,从本地文件系统提取/common.js文件,本地是存在这个文件的,所以返回了文件内容“
// this a test js file”,同时返回http状态码200。
下面我们在redis里存入这个key:
[root@vm5 conf]# redis-cli
redis 127.0.0.1:6379> set '/common.js' '// fetch from redis'
OK
redis 127.0.0.1:6379> keys *
1) "/common.js"
再次请求
[root@vm5 conf]# curl -i localhost/common.js
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Wed, 20 Feb 2013 19:23:13 GMT
Content-Type: application/x-javascript
Content-Length: 19
Connection: keep-alive

// fetch from redis
ok,结果如我们预期

方案二、使用HttpRedis2Module
1、配置nginx.conf
worker_processes 1;
error_log logs/error.log debug;
events {
        worker_connections 1024;
}
http {
        include mime.types;
        default_type application/octet-stream;
        sendfile on;
        keepalive_timeout 65;
        server {
                listen 80;
                server_name localhost;
                root html;
                index index.html index.htm;
                location /get {
                        set_unescape_uri $key $arg_key;
                        redis2_query get $key;
                        redis2_pass 127.0.0.1:6379;
                }
                location /set {
                        set_unescape_uri $key $arg_key;
                        set_unescape_uri $val $arg_val;
                        redis2_query set $key $val;
                        redis2_pass 127.0.0.1:6379;
                }
        }
}

2、测试配置并重启nginx
3、测试
[root@vm5 conf]# curl -i localhost/get?key=/common.js
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Wed, 20 Feb 2013 19:49:57 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive

$19
// fetch from redis
[root@vm5 conf]# curl -i 'localhost/set?key=/common.js&val=set by nginx'
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Wed, 20 Feb 2013 19:50:41 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive

+OK
[root@vm5 conf]# curl -i localhost/get?key=/common.js
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Wed, 20 Feb 2013 19:50:45 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive

$12
set by nginx

ok,结果出来了,其中的$19和$12是返回的数据长度。

方案三、使用HttpLuaModule模块的lua-resty-redis库
1、配置nginx.conf
worker_processes 1;
error_log logs/error.log debug;
events {
        worker_connections 1024;
}
http {
        include mime.types;
        default_type application/octet-stream;
        sendfile on;
        keepalive_timeout 65;
        server {
                listen 80;
                server_name localhost;
                root html;
                index index.html index.htm;
                location / {
                        content_by_lua_file conf/lua/redis.lua;
                }
        }
}
其中conf/lua/redis.lua代码如下
local cmd = tostring(ngx.var.arg_cmd)
local key = tostring(ngx.var.arg_key)
local val = tostring(ngx.var.arg_val)
local commands = {
        get="get",
        set="set"
}
cmd = commands[cmd]
if not cmd then
        ngx.say("command not found!")
        ngx.exit(400)
end

local redis = require("resty.redis")
local red = redis:new()

red:set_timeout(1000) -- 1 second

local ok,err = red:connect("127.0.0.1",6379)
if not ok then
        ngx.say("failed to connect: ",err)
        return
end

if cmd == "get" then
        if not key then ngx.exit(400) end
        local res,err = red:get(key)
        if not res then
                ngx.say("failed to get ",key,": ",err)
                return
        end
        ngx.say(res)
end

if cmd == "set" then
        if not (key and val) then ngx.exit(400) end
        local ok,err = red:set(key,val)
        if not ok then
                ngx.say("failed to set ",key,": ",err)
                return
        end
        ngx.say(ok)
end

2、测试配置并重启nginx
3、测试
[root@vm5 conf]# curl -i 'localhost/?cmd=set&key=/common.js&val=set by lua_resty_redis'
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Wed, 20 Feb 2013 20:20:07 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive

OK
[root@vm5 conf]# curl -i 'localhost/?cmd=get&key=/common.js'
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Wed, 20 Feb 2013 20:20:15 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive

set by lua_resty_redis

ok,结果也是我们所预期的,大功告成!
最后这个方案比较灵活,要想在线上使用,需要编写处理逻辑!