1、前言
Lua和OpenResty安裝請參考該鏈接:https://blog.csdn.net/pkxwyf/article/details/105360507
2、需求分析
類似京東首頁的廣告數據顯示:
3、廣告緩存架構概述
- 查詢Ngin緩存,如果有緩存則直接將緩存中的廣告數據返回
- 如果Nginx緩存中沒有廣告數據,則通過Lua腳本查詢Redis,如果Redis中有數據,則將數據存入到Nginx的緩存並返回查詢到廣告數據。
- 如果Redis中沒有緩存數據,則此時會通過Lua腳本查詢MySQL,如果MySQL有數據,則將數據存入到Redis中並返回查詢到數據。
4、廣告表結構
4.1、廣告分類表
CREATE TABLE `tb_content_category` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
4.2、廣告表
CREATE TABLE `tb_content` (
`id` bigint NOT NULL AUTO_INCREMENT,
`category_id` bigint NOT NULL,
`title` varchar(200) DEFAULT NULL,
`url` varchar(500) DEFAULT NULL,
`pic` varchar(300) DEFAULT NULL,
`status` varchar(1) DEFAULT NULL,
`sort_order` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
5、代碼實現
5.1、緩存預熱
緩存預熱就是將數據提前加入到緩存中,當數據發生變更,再將最新的數據更新到緩存。
5.1.1、實現思路
- 定義請求:用於查詢MySQL數據庫中的數據更新到redis中。
- 連接Mysql 按照廣告分類ID讀取廣告列表,轉換爲json字符串。
- 連接Redis將廣告列表json字符串存入redis 。
5.1.2、實現步驟
- 定義請求:請求地址:/content_update 請求參數:id -- 廣告分類id 返回值:json
- 在/root/lua目錄下創建content_update.lua 實現連接Mysql 查詢數據 並存儲到Redis中。
ngx.header.content_type="application/json;charset=utf-8";
local id= ngx.req.get_uri_args()["id"];--提取參數
local cjson= require("cjson"); --加載cjson模塊
local mysql= require("resty.mysql");--加載mysql模塊
local redis= require("resty.redis");--加載redis模塊
--讀取mysql中的數據
local db= mysql:new();
local props = {
host = "192.168.33.133",
port = 3306,
database ="changgou_content",
user ="root",
password ="root"
}
db:connect(props);
local select_sql="select pic,url from tb_content where status = '1' and category_id="..id.." order by sort_orde
r ";
local res=db:query(select_sql);
db:close();
--寫入redis
local red= redis:new();
red:connect("192.168.33.133",6379);
red:set("content_"..id,cjson.encode(res));
red:close();
ngx.say("{falg:true,code:20000}");
- 修改 /usr/local/openresty/nginx/conf/nginx.conf 文件
location /content_update {
content_by_lua_file /root/lua/content_update.lua;
}
- 重新啓動nginx並測試:http://192.168.33.133/content_update?id=1
5.2、廣告緩存讀取
5.2.1、實現思路
- 定義請求:用戶根據廣告分類的ID 獲取廣告的列表
- 從Nginx緩存獲取,獲取到直接返回廣告數據,否則執行下一步
- 從Redis中獲取廣告數據,獲取到則將廣告數據存入Nginx緩存中
5.2.2、實現步驟
- 定義請求:請求地址:/content_read 請求參數:id -- 廣告分類id 返回值:json
- 在/root/lua目錄下創建content_read.lua 實現查詢nginx緩存數據
ngx.header.content_type="application/json;charset=utf‐8";
‐‐提取參數:廣告分類id
local id= ngx.req.get_uri_args()["id"];
‐‐加載本地緩存模塊
local cache_ngx= ngx.shared.dis_cache;
‐‐從本地緩存獲取廣告數據
local content_cache = cache_ngx:get("content_"..id);
‐‐ 如果本地緩存沒有數據
if content_cache =="" or content_cache == nil then
‐‐引入redis模塊
local redis= require("resty.redis");
‐‐實例化redis對象
local red = redis:new();
‐‐建立連接
red:connect("192.168.33.133",6379);
‐‐從redis取值
local data= red:get("content_"..id);
‐‐關閉連接
red:close();
ngx.say(data);
‐‐存入本地緩存
cache_ngx:set("content_"..id , data);
else
ngx.say(content_cache);
end
- 修改 /usr/local/openresty/nginx/conf/nginx.conf 文件
location /content_read {
content_by_lua_file /root/lua/content_read.lua;
}
- 重新啓動nginx並測試:http://192.168.33.133/content_read?id=1