1.前言
一般会部署多个nginx,每个nginx也有本地缓存,这里会带来命中率的问题,为什么呢?比如说,对于同个商品,每次请求时,可能会路由到不同的nginx中。解决方法,使用分发层nginx+应用层nginx解决此问题。
2.分发到应用层nginx流程
- 获取请求参数,比如productId
- 对productId进行hash
- hash值对应用层nginx数量取模,获取到一个应用层nginx
- 利用http发送请求到应用层nginx
- 获取响应后返回
3.引入lua http lib包
#cd /usr/servers/lualib/resty/
#wget https://codechina.csdn.net/mirrors/pintsized/lua-resty-http/-/tree/master/lib/resty/http_headers.lua
#wget https://codechina.csdn.net/mirrors/pintsized/lua-resty-http/-/tree/master/lib/resty/http.lua
4.规划lua项目结构
/usr/lua/eshop
eshop
eshop.conf
lua
distribute.lua
lualib
*.lua
*.so
5.在nginx中配置eshop.conf
# vi /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/servers/lualib/?.lua;;";
lua_package_cpath "/usr/servers/lualib/?.so;;";
include /usr/lua/eshop/eshop.conf;
}
5.配置eshop.conf
#mkdir -p /usr/lua/eshop/
#vi /usr/lua/eshop/eshop.conf
server {
listen 80;
server_name _;
location /product{
default_type 'text/html';
lua_code_cache off;
content_by_lua_file /usr/lua/eshop/lua/distribute.lua;
}
}
6.编写distribute.lua
# mkdir -p /usr/lua/eshop/lua
# vi /usr/lua/eshop/lua/distribute.lua
local uri_args = ngx.req.get_uri_args()
local productId = uri_args["productId"]
local host = {"192.168.135.132", "192.168.135.136"}
local hash = ngx.crc32_long(productId)
hash = (hash % 2) + 1
backend = "http://"..host[hash]
local method = uri_args["method"]
local requestBody = "/"..method.."?productId="..productId
local http = require("resty.http")
local httpc = http.new()
local resp, err = httpc:request_uri(backend, {
method = "GET",
path = requestBody
})
if not resp then
ngx.say("request error :", err)
return
end
ngx.say(resp.body)
httpc:close()
7.nginx动态生效
/usr/servers/nginx/sbin/nginx -s reload
8.测试
在132和136机器上部署相应的lua脚本后,进行测试,得到结果如下:
http://192.168.135.135/eshop?method=product&productId=4
hi, 192.168.135.132
http://192.168.135.135/eshop?method=product&productId=1
hi, 192.168.135.136
至此,根据productId,能够打到一个固定的应用层nginx上了。