1. OpenResty簡(jiǎn)介
點(diǎn)擊查看官網(wǎng)
OpenResty是一個(gè)基于Nginx與Lua的高性能Web平臺(tái)袁辈,其內(nèi)部集成了大量精良的Lua庫(kù)、第三方模塊以及大多數(shù)的依賴項(xiàng)饶囚。用于方便地搭建能夠處理超高并發(fā)匿又、擴(kuò)展性極高的動(dòng)態(tài)Web應(yīng)用敬辣、Web 服務(wù)和動(dòng)態(tài)網(wǎng)關(guān)牛哺。
OpenResty通過(guò)匯聚各種設(shè)計(jì)精良的Nginx模塊(主要由OpenResty團(tuán)隊(duì)自主開發(fā)),從而將Nginx有效地變成一個(gè)強(qiáng)大的通用Web應(yīng)用平臺(tái)篙耗。這樣迫筑,Web開發(fā)人員和系統(tǒng)工程師可以使用Lua腳本語(yǔ)言調(diào)動(dòng)Nginx支持的各種C以及Lua模塊,快速構(gòu)造出足以勝任10K乃至1000K以上單機(jī)并發(fā)連接的高性能Web應(yīng)用系統(tǒng)宗弯。
OpenResty的目標(biāo)是讓你的Web服務(wù)直接跑在Nginx服務(wù)內(nèi)部脯燃,充分利用Nginx的非阻塞I/O模型,不僅僅對(duì)HTTP客戶端請(qǐng)求,甚至于對(duì)遠(yuǎn)程后端諸如MySQL蒙保、PostgreSQL辕棚、Memcached以及Redis等都進(jìn)行一致的高性能響應(yīng)。
某些大型網(wǎng)站廣告的訪問(wèn)流程
流程:
- 查詢Ngin緩存追他,如果有緩存則直接將緩存中的廣告數(shù)據(jù)返回
- 如果Nginx緩存中沒有廣告數(shù)據(jù)坟募,則通過(guò)Lua腳本查詢Redis岛蚤,如果Redis中有數(shù)據(jù)邑狸,則將數(shù)據(jù)存入到Nginx的緩存并返回查詢到廣告數(shù)據(jù)。
- 如果Redis中沒有緩存數(shù)據(jù)涤妒,則此時(shí)會(huì)通過(guò)Lua腳本查詢MySQL单雾,如果MySQL有數(shù)據(jù),則將數(shù)據(jù)存入到Redis中并返回查詢到數(shù)據(jù)她紫。
2. 例子
請(qǐng)先確保到官網(wǎng)查看并下載安裝OpenResty后再繼續(xù)操作硅堆。
1. 表結(jié)構(gòu)
- 廣告分類表
CREATE TABLE `tb_content_category` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
- 廣告表
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 DEFAULT CHARSET=utf8mb4
請(qǐng)自行填充數(shù)據(jù)哦~~~
2. 代碼實(shí)現(xiàn)
緩存預(yù)熱
緩存預(yù)熱就是將數(shù)據(jù)提前加入到緩存中,當(dāng)數(shù)據(jù)發(fā)生變更贿讹,再將最新的數(shù)據(jù)更新到緩存渐逃。
實(shí)現(xiàn)思路
- 定義請(qǐng)求:用于查詢MySQL數(shù)據(jù)庫(kù)中的數(shù)據(jù)更新到redis中。
- 連接Mysql 按照廣告分類ID讀取廣告列表民褂,轉(zhuǎn)換為json字符串茄菊。
- 連接Redis將廣告列表json字符串存入redis 。
- 實(shí)現(xiàn)步驟
- 定義請(qǐng)求:請(qǐng)求地址:/content_update 請(qǐng)求參數(shù):id -- 廣告分類id 返回值:json
在/root/lua目錄下創(chuàng)建content_update.lua 實(shí)現(xiàn)連接Mysql 查詢數(shù)據(jù) 并存儲(chǔ)到Redis中赊堪。
- content_update.lua
ngx.header.content_type="application/json;charset=utf-8";
local id= ngx.req.get_uri_args()["id"];--提取參數(shù)
local cjson= require("cjson"); --加載cjson模塊
local mysql= require("resty.mysql");--加載mysql模塊
local redis= require("resty.redis");--加載redis模塊
--讀取mysql中的數(shù)據(jù)
local db= mysql:new();
local props = {
host = "192.168.1.101",
port = 3306,
database ="mybatis",
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_order ";
local res=db:query(select_sql);
db:close();
--寫入redis
local red= redis:new();
red:set_timeout=(2000);
local ok, err = red:connect("192.168.1.100",6379);
if not ok then
ngx.say("failed to connect:", err)
return
end
--redis認(rèn)證
local _res, err = res:auth("redis123456");
if not _res then
ngx.say("failed to authenticate:", err)
return
end
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;
}
- 重新啟動(dòng)nginx并測(cè)試:http://192.168.1.7/content_update?id=1
廣告緩存讀取
** 實(shí)現(xiàn)思路**
- 定義請(qǐng)求:用戶根據(jù)廣告分類的ID 獲取廣告的列表
- 從Nginx緩存獲取面殖,獲取到直接返回廣告數(shù)據(jù),否則執(zhí)行下一步
從Redis中獲取廣告數(shù)據(jù)哭廉,獲取到則將廣告數(shù)據(jù)存入Nginx緩存中- 實(shí)現(xiàn)步驟
- 定義請(qǐng)求:請(qǐng)求地址:/content_read 請(qǐng)求參數(shù):id -- 廣告分類id 返回值:json
- 在/root/lua目錄下創(chuàng)建content_read.lua 實(shí)現(xiàn)查詢nginx緩存數(shù)據(jù)
content_read.lua
ngx.header.content_type="application/json;charset=utf-8";
--提取參數(shù):廣告分類id
local id= ngx.req.get_uri_args()["id"];
--加載本地緩存模塊
local cache_ngx= ngx.shared.dis_cache;
--從本地緩存獲取廣告數(shù)據(jù)
local content_cache = cache_ngx:get("content_"..id);
--如果本地緩存沒有數(shù)據(jù)
if content_cache =="" or content_cache == nil then
--引入redis模塊
local redis= require("resty.redis");
--實(shí)例化redis對(duì)象
local red = redis:new();
--超時(shí)
red:set_timeout=(2000);
--建立連接
local ok, err = red:connect("192.168.1.100",6379);
if not ok then
ngx.say("failed to connect:", err)
return
end
--redis認(rèn)證
local _res, err = res:auth("redis123456");
if not _res then
ngx.say("failed to authenticate:", err)
return
end
--從redis取值
local data= red:get("content_"..id);
--關(guān)閉連接
red:close();
ngx.say(data);
--存入本地緩存
cache_ngx:set("content_"..id , data);
else
ngx.say(content_cache);
end
- 修改 /usr/local/openresty/nginx/conf/nginx.conf 文件
# 定義lua緩存命名空間(在http幾點(diǎn)下)
lua_shared_dict dis_cache 128m;
location /content_read {
content_by_lua_file /root/lua/content_read.lua;
}
- 重新啟動(dòng)nginx并測(cè)試:http://192.168.1.7/content_read?id=1
如果覺得有收獲脊僚,歡迎點(diǎn)贊和評(píng)論,更多知識(shí)遵绰,請(qǐng)點(diǎn)擊關(guān)注查看我的主頁(yè)信息哦~