OpenResty+Lua+Redis實現廣告多級緩存

1、前言

Lua和OpenResty安裝請參考該鏈接:https://blog.csdn.net/pkxwyf/article/details/105360507

2、需求分析

類似京東首頁的廣告數據顯示:

3、廣告緩存架構概述

  1. 查詢Ngin緩存,如果有緩存則直接將緩存中的廣告數據返回
  2. 如果Nginx緩存中沒有廣告數據,則通過Lua腳本查詢Redis,如果Redis中有數據,則將數據存入到Nginx的緩存並返回查詢到廣告數據。
  3. 如果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;
}

 

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章