参考文章
http://jinnianshilongnian.iteye.com/blog/2188113
conf文件与原来文章的配置有点不同,这个要参考官方文档http://nginx.org/en/docs/http/ngx_http_upstream_module.html
vim /usr/chapter6/nginx_chapter6.conf
upstream backend {
server 192.168.1.111:8080 max_fails=5 fail_timeout=10s weight=1;
server 192.168.1.111:8090 max_fails=5 fail_timeout=10s weight=1;
server 192.168.1.111:8080 backup;
server 192.168.1.111:8090 backup;
keepalive 100;
}
server {
listen 80;
server_name _;
location ~ /backend/(.*) {
keepalive_timeout 30s;
keepalive_requests 100;
rewrite /backend(/.*) $1 break;
#之后该服务将只有内部使用,ngx.location.capture
proxy_pass_request_headers off;
#more_clear_input_headers Accept-Encoding;
proxy_next_upstream error timeout;
proxy_pass http://backend;
}
location ~ ^/ad/(\d+)$ {
default_type 'text/html';
charset utf-8;
lua_code_cache on;
set $id $1;
content_by_lua_file /usr/chapter6/ad.lua;
}
}
lua文件
local redis = require("resty.redis")
local cjson = require("cjson")
local cjson_encode = cjson.encode
local ngx_log = ngx.log
local ngx_ERR = ngx.ERR
local ngx_exit = ngx.exit
local ngx_print = ngx.print
local ngx_re_match = ngx.re.match
local ngx_var = ngx.var
local function close_redis(red)
if not red then
return
end
--释放连接(连接池实现)
local pool_max_idle_time = 10000 --毫秒
local pool_size = 100 --连接池大小
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 function read_redis(id)
local red = redis:new()
red:set_timeout(1000)
local ip = "127.0.0.1"
local port = 1111
local ok, err = red:connect(ip, port)
if not ok then
ngx_log(ngx_ERR, "connect to redis error : ", err)
return close_redis(red)
end
local resp, err = red:get(id)
if not resp then
ngx_log(ngx_ERR, "get redis content error : ", err)
return close_redis(red)
end
--得到的数据为空处理
if resp == ngx.null then
resp = nil
end
close_redis(red)
return resp
end
local function read_http(id)
local resp = ngx.location.capture("/backend/ad", {
method = ngx.HTTP_GET,
args = {id = id}
})
if not resp then
ngx_log(ngx_ERR, "request error :", err)
return
end
if resp.status ~= 200 then
ngx_log(ngx_ERR, "request error, status :", resp.status)
return
end
return resp.body
end
--获取id
local id = ngx_var.id
--从redis获取
local content = read_redis(id)
--如果redis没有,回源到tomcat
if not content then
ngx_log(ngx_ERR, "redis not found content, back to http, id : ", id)
content = read_http(id)
end
--如果还没有返回404
if not content then
ngx_log(ngx_ERR, "http not found content, id : ", id)
return ngx_exit(404)
end
--输出内容
ngx.print("show_ad(")
ngx_print(cjson_encode({content = content}))
ngx.print(")")
- 获取参数id后,先访问redis读取数据,若没有读到响应的数据,
则会在error.log中打印错误日志,然后用http get访问tomcat,从mysql数据库查询
ngx_log(ngx_ERR, "redis not found content, back to http, id : ", id)
- 若在redis中读到数据,则不会访问http
日志