大家可以自己按照上一講講解的內(nèi)容,基于OpenResty在另外兩臺機(jī)器上都部署一下nginx+lua的開發(fā)環(huán)境
我已經(jīng)在eshop-cache02和eshop-cache03上都部署好了
我這邊的話呢,是打算用eshop-cache01和eshop-cache02作為應(yīng)用層nginx服務(wù)器,用eshop-cache03作為分發(fā)層nginx
在eshop-cache03,也就是分發(fā)層nginx中,編寫lua腳本,完成基于商品id的流量分發(fā)策略
當(dāng)然了,我們這里主要會簡化策略,簡化業(yè)務(wù)邏輯,實際上在你的公司中,你可以隨意根據(jù)自己的業(yè)務(wù)邏輯和場景,去制定自己的流量分發(fā)策略
1、獲取請求參數(shù),比如productId
2、對productId進(jìn)行hash
3、hash值對應(yīng)用服務(wù)器數(shù)量取模,獲取到一個應(yīng)用服務(wù)器
4、利用http發(fā)送請求到應(yīng)用層nginx
5、獲取響應(yīng)后返回
這個就是基于商品id的定向流量分發(fā)的策略,lua腳本來編寫和實現(xiàn)
我們作為一個流量分發(fā)的nginx,會發(fā)送http請求到后端的應(yīng)用nginx上面去,所以要先引入lua http lib包
cd /usr/hello/lualib/resty/
wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http_headers.lua
wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http.lua
代碼:
local uri_args = ngx.req.get_uri_args()
local productId = uri_args["productId"]
local host = {"192.168.31.19", "192.168.31.187"}
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()
/usr/servers/nginx/sbin/nginx -s reload
基于商品id的定向流量分發(fā)策略的lua腳本就開發(fā)完了,而且也測試過了
我們就可以看到,如果你請求的是固定的某一個商品,那么就一定會將流量打到固定的一個應(yīng)用nginx上面去
腳本事例
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()