如下图所示: 当我们nginx部署高可用的时候,客户的请求不知道落在那个nginx上 1,当我们第一次请求落在 第一台nginx(最左)上,发现nginx本地并没有缓存, 2,nginx就必须到redis获取数据,并缓存到本地 3,将请求数据返回给客户
第二次请求理想情况下 如果我们得请求落在第一台(最左),nginx发现本地已经有缓存了, 那么可以直接返回不用请求redis
不理想情况, 当我们得第二次请求没有落在第一台机器上,落在了中间那台,nginx就发现本地还是没有缓存 会到redis集群中获取数据,并缓存本地,返回给客户。。 这样的情况下,nginx的本地缓存命中率就很低了。。。这样会导致redis的压力暴增。。

经上面的分析,我们知道了nginx命中率低的原因,就是同一个请求(getProductInfo?productId=1)被分发到不同的nginx上面,那么我们可以想办法让获取同一个数据(productId=1)的请求落在同一个nginx上面,如下图所示:

我们使用双层nginx 第一层(nginx4和5)作为分发层,做分发作用;;; 第二层(nginx1和2和3) 作为应用层,提供本地缓存的作用;;;
当我们的请求过来经nginx4。nginx4+lua脚本获取请求参数(productId取模)判断要将请求分给(nginx 1 2 3)哪一台机器。。假设是nginx1 nginx判断本地没有缓存就去redis获取并缓存到本地,
当我们得第二次同一个请求过来,nginx5,,同样取参数取模。将请求分发给nginx1,,这样nginx就不用再去redis获取了,可以直接返回。
自行查阅资料
项目工程结构
hello
hello.conf
lua
hello.lua
lualib
*.lua
*.so
放在/usr/hello目录下
/usr/servers/nginx/conf/nginx.conf
worker_processes 2;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type text/html;
lua_package_path "/usr/hello/lualib/?.lua;;";
lua_package_cpath "/usr/hello/lualib/?.so;;";
include /usr/hello/hello.conf;
}
/usr/hello/hello.conf
server {
listen 80;
server_name _;
location /lua {
default_type 'text/html';
lua_code_cache off;
content_by_lua_file /usr/example/lua/test.lua;
}
} 部署分发层nginx以及基于lua完成基于商品id的定向流量分发策略
//hello.lua
local uri_args = ngx.req.get_uri_args()
local productId = uri_args["productId"]
local hosts = {"192.168.31.187", "192.168.31.19"}
local hash = ngx.crc32_long(productId)
local index = (hash % 2) + 1
backend = "http://"..hosts[index]
local requestPath = uri_args["requestPath"]
requestPath = "/"..requestPath.."?productId="..productId
local http = require("resty.http")
local httpc = http.new()
local resp, err = httpc:request_uri(backend,{
method = "GET",
path = requestPath
})
if not resp then
ngx.say("request error: ", err)
return
end
ngx.say(resp.body)
httpc:close() 如果应用层某一台nginx宕机,,请求取模的参数要变更??
lua脚本如何时时判断应用层的活的nginx数量
或者,lua请求应用层失败在换一台??
了解一下zuul网关能否替换分发层