# 081. 在 nginx+lua 中实现热点缓存自动降级为负载均衡流量分发策略的逻辑

之前思路已经有了:通过 storm 反推过来的

/usr/hello/lua/distribute.lua









 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 






























local uri_args = ngx.req.get_uri_args()
-- 获取参数
local productId = uri_args["productId"]
local shopId = uri_args["shopId"]

-- 定义后端应用 ip
local host = {"192.168.99.170", "192.168.99.171"}

local hot_product_key = "hot_product_"..productId
local cache_ngx = ngx.shared.my_cache
local hot_product_flag = cache_ngx:get(hot_product_key)

local backend = ""
if hot_product_flag == "true" then
	-- 设置随机数种子
	math.randomseed(tostring(os.time()):reverse():sub(1, 7))
	local index = math.random(1, 2)
	backend = "http://"..host[index]
else
	-- 对商品 id 取模并计算 hash 值
	local hash = ngx.crc32_long(productId)
	hash = (hash % 2) + 1
	-- 拼接 http 前缀
	backend = "http://"..host[hash]
end

-- 获取到参数中的路径,比如你要访问 /hello,这个例子中是需要传递访问路径的
local method = uri_args["method"]
-- 拼接具体的访问地址不带 host,如:/hello?productId=1
local requestBody = "/"..method.."?productId="..productId.."&shopId="..shopId

-- 获取 http 包
local http = require("resty.http")
local httpc = http.new()

-- 访问,这里有疑问:万一有 cooke 这些脚本支持吗?会很麻烦吗?
local resp, err = httpc:request_uri(backend, {
    method = "GET",
    path = requestBody,
    keepalive=false
})

-- 如果没有响应则输出一个 err 信息
if not resp then
    ngx.say("request error :", err)
    return
end

-- 有响应测输出响应信息
ngx.say(resp.body)  

-- 关闭 http 客户端实例
httpc:close()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54