OpenResty 这里就不介绍了,可以阅读 OpenResty(nginx)操作mysql的初步应用 或 参阅 http://openresty.org
c、测试
看到了吧,在 http 头里加入了 Last-Modified,没开启 memc_flags_to_last_modified 时是没有这个http头的。
我们修改刚才请求的 key 值
我们再请求一次
这次仍然使用的是老的时间戳,服务器端对比客户端发送的时间戳和从memcached获取的时间戳,发现不一致,就发送新内容到客户端,这里我们得到了新值 33
其中 conf/lua/memcached.lua 代码如下:
ok,效果出来了,确实强大!赞一个!
要想在nginx里访问memcached,需要模块 HttpMemcachedModule 或 HttpMemcModule,本文使用的是后者。前者可操作memcached的指令较少,一般用于简单的缓存,并且第一次取数据时需要依赖其他逻辑返回数据才能存储进memcached。而后者可操作memcached的指令较多,灵活,功能比较强大。如果安装
OpenResty时没有显示的禁止http_memc_module模块,默认是开启的。
OpenResty的安装比较简单,在此略了,可以阅读 OpenResty(nginx)操作mysql的初步应用 里关于
OpenResty的安装部分。另外也可以通过nginx模块HttpLuaModule的lua-resty-memcached库来操作。
方法一
通过
HttpMemcModule模块
1、配置 nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream memcached {
server 127.0.0.1:11211;
}
server {
listen 80;
server_name localhost;
root html;
index index.html index.htm;
location = /memcached-status {
set $memc_cmd stats;
memc_pass memcached;
}
location / {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_value $arg_val;
set $memc_flags $arg_flags;
set $memc_exptime $arg_exptime;
memc_cmds_allowed get set add incr delete flush_all;
memc_pass memcached;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream memcached {
server 127.0.0.1:11211;
}
server {
listen 80;
server_name localhost;
root html;
index index.html index.htm;
location = /memcached-status {
set $memc_cmd stats;
memc_pass memcached;
}
location / {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_value $arg_val;
set $memc_flags $arg_flags;
set $memc_exptime $arg_exptime;
memc_cmds_allowed get set add incr delete flush_all;
memc_pass memcached;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
2、测试配置文件,并重启服务
[root@vm5 ~]# /usr/local/openresty/nginx/sbin/nginx -t -c /usr/local/openresty/nginx/conf/nginx.conf
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@vm5 ~]# killall -HUP nginx
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@vm5 ~]# killall -HUP nginx
3、测试结果
[root@vm5 conf]# curl 'localhost/?cmd=set&key=1&val=zhangsan'
STORED
[root@vm5 conf]# curl 'localhost/?cmd=get&key=1'
zhangsan
[root@vm5 conf]# curl 'localhost/?cmd=delete&key=1'
DELETED
[root@vm5 conf]# curl 'localhost/?cmd=add&key=2&val=100'
STORED
[root@vm5 conf]# curl 'localhost/?cmd=get&key=2'
100
[root@vm5 conf]# curl 'localhost/?cmd=incr&key=2&val=1'
101
[root@vm5 conf]# curl 'localhost/?cmd=incr&key=2&val=1'
102
[root@vm5 conf]# curl 'localhost/?cmd=decr&key=2&val=1'
403 Forbidden
ngx_openresty/1.2.4.14
[root@vm5 conf]# curl 'localhost/?cmd=flush_all'
OK
[root@vm5 conf]# curl 'localhost/?cmd=get&key=1'
404 Not Found
ngx_openresty/1.2.4.14
[root@vm5 conf]# curl 'localhost/?cmd=get&key=2'
404 Not Found
ngx_openresty/1.2.4.14
[root@vm5 conf]# curl 'localhost/memcached-status'
STAT pid 4914
STAT uptime 2774
STAT time 1360198988
STAT version 1.4.15
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.014997
STAT rusage_system 0.015997
STAT curr_connections 5
STAT total_connections 46
STAT connection_structures 6
STAT reserved_fds 20
STAT cmd_get 35
STAT cmd_set 8
STAT cmd_flush 5
STAT cmd_touch 0
STAT get_hits 11
STAT get_misses 24
STAT delete_misses 0
STAT delete_hits 1
STAT incr_misses 0
STAT incr_hits 4
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 611
STAT bytes_written 1584
STAT limit_maxbytes 33554432
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT bytes 0
STAT curr_items 0
STAT total_items 11
STAT expired_unfetched 1
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 1
END
STORED
[root@vm5 conf]# curl 'localhost/?cmd=get&key=1'
zhangsan
[root@vm5 conf]# curl 'localhost/?cmd=delete&key=1'
DELETED
[root@vm5 conf]# curl 'localhost/?cmd=add&key=2&val=100'
STORED
[root@vm5 conf]# curl 'localhost/?cmd=get&key=2'
100
[root@vm5 conf]# curl 'localhost/?cmd=incr&key=2&val=1'
101
[root@vm5 conf]# curl 'localhost/?cmd=incr&key=2&val=1'
102
[root@vm5 conf]# curl 'localhost/?cmd=decr&key=2&val=1'
403 Forbidden
[root@vm5 conf]# curl 'localhost/?cmd=flush_all'
OK
[root@vm5 conf]# curl 'localhost/?cmd=get&key=1'
404 Not Found
[root@vm5 conf]# curl 'localhost/?cmd=get&key=2'
404 Not Found
[root@vm5 conf]# curl 'localhost/memcached-status'
STAT pid 4914
STAT uptime 2774
STAT time 1360198988
STAT version 1.4.15
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.014997
STAT rusage_system 0.015997
STAT curr_connections 5
STAT total_connections 46
STAT connection_structures 6
STAT reserved_fds 20
STAT cmd_get 35
STAT cmd_set 8
STAT cmd_flush 5
STAT cmd_touch 0
STAT get_hits 11
STAT get_misses 24
STAT delete_misses 0
STAT delete_hits 1
STAT incr_misses 0
STAT incr_hits 4
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 611
STAT bytes_written 1584
STAT limit_maxbytes 33554432
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT bytes 0
STAT curr_items 0
STAT total_items 11
STAT expired_unfetched 1
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 1
END
4、也可以根据LM(Last Modified)实现304缓存
a、修改 nginx 配置文件,在 location / 段里加入下面指令
memc_flags_to_last_modified on;
b、测试并重启 nginx
[root@vm5 ~]# /usr/local/openresty/nginx/sbin/nginx -t -c /usr/local/openresty/nginx/conf/nginx.conf
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@vm5 ~]# killall -HUP nginx
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@vm5 ~]# killall -HUP nginx
[root@vm5 conf]# curl -i 'localhost/?cmd=get&key=1'
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 09:25:03 GMT
Content-Type: text/plain
Content-Length: 2
Last-Modified: Thu, 07 Feb 2013 01:22:26 GMT
Connection: keep-alive
22
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 09:25:03 GMT
Content-Type: text/plain
Content-Length: 2
Last-Modified: Thu, 07 Feb 2013 01:22:26 GMT
Connection: keep-alive
22
我们再加头访问一次
[root@vm5 conf]# curl -H 'If-Modified-Since: Thu, 07 Feb 2013 01:22:26 GMT' -i 'localhost/?cmd=get&key=1'
HTTP/1.1 304 Not Modified
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 09:29:45 GMT
Last-Modified: Thu, 07 Feb 2013 01:22:26 GMT
Connection: keep-alive
HTTP/1.1 304 Not Modified
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 09:29:45 GMT
Last-Modified: Thu, 07 Feb 2013 01:22:26 GMT
Connection: keep-alive
[root@vm5 conf]# date +%s
1360229729
[root@vm5 conf]# curl -i 'localhost/?cmd=set&key=1&val=33&flags= 1360229729'
HTTP/1.1 201 Created
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 09:35:47 GMT
Content-Type: text/plain
Content-Length: 8
Connection: keep-alive
STORED
1360229729
[root@vm5 conf]# curl -i 'localhost/?cmd=set&key=1&val=33&flags= 1360229729'
HTTP/1.1 201 Created
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 09:35:47 GMT
Content-Type: text/plain
Content-Length: 8
Connection: keep-alive
STORED
[root@vm5 conf]# curl -H 'If-Modified-Since: Thu, 07 Feb 2013 01:22:26 GMT' -i 'localhost/?cmd=get&key=1'
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 09:37:51 GMT
Content-Type: text/plain
Content-Length: 2
Last-Modified: Thu, 07 Feb 2013 09:35:29 GMT
Connection: keep-alive
33
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 09:37:51 GMT
Content-Type: text/plain
Content-Length: 2
Last-Modified: Thu, 07 Feb 2013 09:35:29 GMT
Connection: keep-alive
33
使用这个特性可以降低不必要的网络流量消耗,节省成本。其实,服务器是将我们传递的flags参数设置到了memcached的set指令对应的flag字段,即:
key flag expire length
set 1 1360229729
0
2
方法二
通过
HttpLuaModule
模块
的lua-resty-memcached库
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;
#default_type 'text/plain';
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root html;
index index.html index.htm;
lua_code_cache on;
location / {
content_by_lua_file conf/lua/memcached.lua;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
error_log logs/error.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#default_type 'text/plain';
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root html;
index index.html index.htm;
lua_code_cache on;
location / {
content_by_lua_file conf/lua/memcached.lua;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
local cmd = tostring(ngx.var.arg_cmd)
local key = tostring(ngx.var.arg_key)
local val = tostring(ngx.var.arg_val)
local flags = tostring(ngx.var.arg_flags or 0)
local exptime = tostring(ngx.var.arg_exptime or 0)
local commands = {
set="set",
get="get",
gets="gets",
add="add",
delete="delete",
flush_all="flush_all",
incr="incr",
decr="decr",
replace="replace",
append="append",
prepend="prepend",
stats="stats",
version="version"
}
cmd = commands[cmd]
if not cmd then ngx.exit(400) end
local memcached = require("resty.memcached")
local memc,err = memcached:new()
if not memc then
ngx.say("failed to instantiate memc: ",err)
return
end
memc:set_timeout(1000)
local ok,err = memc:connect("127.0.0.1",11211)
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,flags,err = memc:get(key)
if err then
ngx.say("failed to get ",key," : ",err)
return
end
if not res then
ngx.exit(404)
end
ngx.say(res)
end
if cmd == "set" then
if not (key and val) then ngx.exit(400) end
local ok,err = memc:set(key,val,exptime,flags)
if not ok then
ngx.say("failed to set ",key," : ",err)
return
end
ngx.say("STORED")
end
local key = tostring(ngx.var.arg_key)
local val = tostring(ngx.var.arg_val)
local flags = tostring(ngx.var.arg_flags or 0)
local exptime = tostring(ngx.var.arg_exptime or 0)
local commands = {
set="set",
get="get",
gets="gets",
add="add",
delete="delete",
flush_all="flush_all",
incr="incr",
decr="decr",
replace="replace",
append="append",
prepend="prepend",
stats="stats",
version="version"
}
cmd = commands[cmd]
if not cmd then ngx.exit(400) end
local memcached = require("resty.memcached")
local memc,err = memcached:new()
if not memc then
ngx.say("failed to instantiate memc: ",err)
return
end
memc:set_timeout(1000)
local ok,err = memc:connect("127.0.0.1",11211)
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,flags,err = memc:get(key)
if err then
ngx.say("failed to get ",key," : ",err)
return
end
if not res then
ngx.exit(404)
end
ngx.say(res)
end
if cmd == "set" then
if not (key and val) then ngx.exit(400) end
local ok,err = memc:set(key,val,exptime,flags)
if not ok then
ngx.say("failed to set ",key," : ",err)
return
end
ngx.say("STORED")
end
2、测试并重启 nginx
3、测试
[root@vm5 conf]# curl -i 'localhost/?cmd=set&key=1&val=this'
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 17:22:21 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
STORED
[root@vm5 conf]# curl -i 'localhost/?cmd=get&key=1'
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 17:22:30 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
this
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 17:22:21 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
STORED
[root@vm5 conf]# curl -i 'localhost/?cmd=get&key=1'
HTTP/1.1 200 OK
Server: ngx_openresty/1.2.4.14
Date: Thu, 07 Feb 2013 17:22:30 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
this