# 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
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