Skip to content

Commit e68be36

Browse files
committed
lua_ad
1 parent 19c7efe commit e68be36

File tree

7 files changed

+659
-0
lines changed

7 files changed

+659
-0
lines changed

lua_ad/adbid.lua

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
--广告竞价请求处理
2+
3+
local cjson = require("cjson")
4+
local ad_cache = require("libs.cache")
5+
local match = require("libs.match")
6+
local bider = require("libs.bid")
7+
local pack = require("libs.pack")
8+
9+
function bid()
10+
--取报文
11+
ngx.req.read_body()
12+
local req_body = ngx.req.get_body_data()
13+
14+
local status, req_body_json = pcall(cjson.decode, req_body)
15+
16+
--json解析失败
17+
if not status then
18+
ngx.log(ngx.ERR, req_body_json)
19+
ngx.say('{"id":"", "nbr":2}')
20+
return
21+
end
22+
23+
--ngx.log(ngx.INFO, req_body)
24+
ngx.ctx.req_body = req_body
25+
26+
ad_cache.cache()
27+
28+
--local cache_ad = ngx.shared.cache_ad
29+
--local orig_ad_stage = cache_ad:get("ad")
30+
--ngx.say(orig_ad_stage)
31+
--local orig_ad_stage_json = cjson.decode(orig_ad_stage)
32+
33+
local match_list = match.match(req_body_json)
34+
if not match_list then
35+
ngx.log(ngx.INFO, "未匹配到合适的广告")
36+
local result = {}
37+
result['id'] = req_body_json.id
38+
result['nbr'] = 8
39+
ngx.say(cjson.encode(result))
40+
return
41+
end
42+
--ngx.say(cjson.encode(match_list))
43+
44+
bid_price, stageid, result, paymode = bider.bid(req_body_json['imp'][1]['bidfloor'], match_list)
45+
if not result then
46+
local result = {}
47+
result['id'] = req_body_json.id
48+
result['nbr'] = 8
49+
ngx.say(cjson.encode(result))
50+
return
51+
end
52+
53+
local result = pack.pack(req_body_json, bid_price, stageid, result, paymode)
54+
if not result then
55+
local result = {}
56+
result['id'] = req_body_json.id
57+
result['nbr'] = 8
58+
ngx.say(cjson.encode(result))
59+
return
60+
end
61+
62+
local resp = cjson.encode(result)
63+
--ngx.log(ngx.INFO, resp)
64+
ngx.ctx.resp = resp
65+
66+
ngx.say(resp)
67+
end
68+
69+
bid()

lua_ad/libs/bid.lua

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
--bid
2+
local redis = require("libs.redis")
3+
local cjson = require("cjson")
4+
5+
local _M = {}
6+
7+
function _M.bid(floor, dict_list)
8+
local low_price = floor
9+
10+
local result = nil
11+
local stageid = -1
12+
local paymode = 1
13+
local bid_price = low_price
14+
local profit = 0
15+
16+
for _, d in ipairs(dict_list) do
17+
while true do
18+
local res = redis.mget_from_redis({'ad:usedmoney:' .. d['ad'].adId,
19+
'ad:usedmoney:' .. d['ad'].adId .. ":" .. tostring(d['stage']['stageId'])})
20+
21+
--ngx.log(ngx.INFO, cjson.encode(res))
22+
--local total_used_money = redis.get_from_redis('ad:usedmoney:' .. d['ad'].adId)
23+
local total_used_money = res[1]
24+
if type(total_used_money) ~= 'string' then
25+
total_used_money = 0
26+
end
27+
total_used_money = tonumber(total_used_money)
28+
29+
--总预算不足
30+
if total_used_money + low_price > tonumber(d['ad'].budget) then
31+
ngx.log(ngx.INFO, '广告:', d['ad'].adId, '总预算不足')
32+
break
33+
end
34+
35+
--local stage_used_money = redis.get_from_redis('ad:usedmoney:' .. d['ad'].adId .. ":" .. tostring(d['stage']['stageId']))
36+
local stage_used_money = res[2]
37+
if type(stage_used_money) ~= 'string' then
38+
stage_used_money = 0
39+
end
40+
stage_used_money = tonumber(stage_used_money)
41+
42+
--阶段预算不足
43+
if stage_used_money + low_price > tonumber(d['stage']['stageBudget']) then
44+
ngx.log(ngx.INFO, '广告', d['ad'].adId, '阶段', tostring(a['stage']['stageId']), '预算不足')
45+
break
46+
end
47+
48+
local high_price = d['stage']['highPrice']
49+
if low_price >= high_price then
50+
break
51+
end
52+
53+
local rand_price = low_price * (1 + 0.02)
54+
55+
if high_price - rand_price >= profit then
56+
profit = high_price - rand_price
57+
result = d['orig']
58+
stageid = d['stage']['stageId']
59+
bid_price = rand_price
60+
end
61+
62+
break
63+
end
64+
end
65+
66+
if not result then
67+
ngx.log(ngx.INFO, '预算不足或者底价太高,不竞价')
68+
return nil, nil, nil, nil
69+
end
70+
71+
--ngx.log(ngx.INFO, '出价', tostring(bid_price))
72+
return bid_price, stageid, result, paymode
73+
end
74+
75+
return _M

lua_ad/libs/cache.lua

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
--mysql缓存到lua_shared_dict
2+
3+
local mysql = require("resty.mysql")
4+
local cjson = require("cjson")
5+
local comm = require("libs.common")
6+
7+
local _M = {}
8+
9+
function _M.cache()
10+
local cache_ad = ngx.shared.cache_ad
11+
ad = cache_ad:get("ad")
12+
13+
--未过期
14+
if ad then
15+
return
16+
end
17+
18+
ngx.log(ngx.INFO, "缓存mysql数据到共享内存")
19+
20+
--当前时间
21+
local now = ngx.localtime()
22+
local m, err = ngx.re.match(now, "([0-9-]+) ([0-9:]+)")
23+
24+
local now_date = nil
25+
local now_time = nil
26+
if m then
27+
now_date = m[1]
28+
now_time = m[2]
29+
else
30+
if err then
31+
ngx.log(ngx.ERR, err)
32+
return
33+
end
34+
ngx.log(ngx.ERR, "match not found")
35+
return
36+
end
37+
38+
--根据当前日期时间和是否投放过滤广告计划表
39+
local db, err = mysql:new()
40+
if not db then
41+
ngx.log(ngx.ERR, "failed to instantiate mysql: " .. err)
42+
return
43+
end
44+
45+
db:set_timeout(1000) -- 1 sec
46+
47+
local ok, err, errno, sqlstate = db:connect{
48+
host = "127.0.0.1",
49+
port = 3306,
50+
database = "adview",
51+
user = "root",
52+
password = "123456",
53+
max_packet_size = 1024 * 1024 }
54+
55+
if not ok then
56+
ngx.log(ngx.ERR, "failed to connect: " .. err .. ": " .. errno .. " " .. sqlstate)
57+
return
58+
end
59+
60+
db:query("SET NAMES utf8")
61+
62+
local res_stage, err, errno, sqlstate =
63+
db:query("select * from advertisement_stage where startdate <= '" .. now_date ..
64+
"' and enddate >= '" .. now_date .. "' and starttime <= '" .. now_time ..
65+
"' and endtime >= '" .. now_time .. "' and isbid = 1")
66+
if not res_stage then
67+
ngx.log(ngx.ERR, "bad result: " .. err .. ": " .. errno .. ": " .. sqlstate)
68+
return
69+
end
70+
71+
if comm.table_is_empty(res_stage) then
72+
ngx.log(ngx.INFO, "暂无广告投放计划, 请确定")
73+
74+
local ok, err = db:set_keepalive(60000, 100)
75+
if not ok then
76+
ngx.log(ngx.ERR, "failed to set keepalive: " .. err)
77+
return
78+
end
79+
80+
return
81+
end
82+
83+
local orig_ad_stage = {}
84+
85+
for _, v in ipairs(res_stage) do
86+
ngx.say(v.originalityId)
87+
local res_orig, err, errno, sqlstate =
88+
db:query("select * from orig where originalityId = '" .. v.originalityId .. "'")
89+
90+
if not res_orig then
91+
ngx.log(ngx.ERR, "bad result: " .. err .. ": " .. errno .. ": " .. sqlstate)
92+
return
93+
end
94+
95+
res_orig = res_orig[1]
96+
97+
if not comm.table_is_empty(res_orig) then
98+
local res_ad, err, errno, sqlstate =
99+
db:query("select * from advertisement where adid = '" .. res_orig.adId ..
100+
"' and startdate <= '" .. now_date .. "' and enddate >= '" .. now_date ..
101+
"' and isbid = 1")
102+
103+
if not res_ad then
104+
ngx.log(ngx.ERR, "bad result: " .. err .. ": " .. errno .. ": " .. sqlstate)
105+
return
106+
end
107+
108+
res_ad = res_ad[1]
109+
110+
111+
if not comm.table_is_empty(res_ad) then
112+
table.insert(orig_ad_stage, {["orig"] = res_orig, ["ad"] = res_ad, ["stage"] = v})
113+
end
114+
115+
end
116+
end
117+
118+
if not comm.table_is_empty(orig_ad_stage) then
119+
cache_ad:set("ad", cjson.encode(orig_ad_stage), 1800)
120+
end
121+
122+
local ok, err = db:set_keepalive(60000, 100)
123+
if not ok then
124+
ngx.log(ngx.ERR, "failed to set keepalive: " .. err)
125+
return
126+
end
127+
128+
end
129+
130+
return _M

lua_ad/libs/common.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
local _M = {}
2+
3+
function _M.table_is_empty(t)
4+
if t == nil or next(t) == nil then
5+
return true
6+
else
7+
return false
8+
end
9+
end
10+
11+
return _M

0 commit comments

Comments
 (0)