OpenResty+Lua+Redis 高性能后端接口

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)流程

流程:

  1. 查詢Ngin緩存追他,如果有緩存則直接將緩存中的廣告數(shù)據(jù)返回
  2. 如果Nginx緩存中沒有廣告數(shù)據(jù)坟募,則通過(guò)Lua腳本查詢Redis岛蚤,如果Redis中有數(shù)據(jù)邑狸,則將數(shù)據(jù)存入到Nginx的緩存并返回查詢到廣告數(shù)據(jù)。
  3. 如果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;
}
廣告緩存讀取

** 實(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;
}

如果覺得有收獲脊僚,歡迎點(diǎn)贊和評(píng)論,更多知識(shí)遵绰,請(qǐng)點(diǎn)擊關(guān)注查看我的主頁(yè)信息哦~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辽幌,一起剝皮案震驚了整個(gè)濱河市增淹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌乌企,老刑警劉巖埠通,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異逛犹,居然都是意外死亡端辱,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門虽画,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)舞蔽,“玉大人,你說(shuō)我怎么就攤上這事码撰∩粒” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵脖岛,是天一觀的道長(zhǎng)朵栖。 經(jīng)常有香客問(wèn)我,道長(zhǎng)柴梆,這世上最難降的妖魔是什么陨溅? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮绍在,結(jié)果婚禮上门扇,老公的妹妹穿的比我還像新娘。我一直安慰自己偿渡,他們只是感情好臼寄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溜宽,像睡著了一般吉拳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上适揉,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天留攒,我揣著相機(jī)與錄音,去河邊找鬼涡扼。 笑死稼跳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吃沪。 我是一名探鬼主播汤善,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了红淡?” 一聲冷哼從身側(cè)響起不狮,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎在旱,沒想到半個(gè)月后摇零,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡桶蝎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年驻仅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片登渣。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡噪服,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胜茧,到底是詐尸還是另有隱情粘优,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布呻顽,位于F島的核電站雹顺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏廊遍。R本人自食惡果不足惜嬉愧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望昧碉。 院中可真熱鬧英染,春花似錦揽惹、人聲如沸被饿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)狭握。三九已至,卻和暖如春疯溺,著一層夾襖步出監(jiān)牢的瞬間论颅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工囱嫩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恃疯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓墨闲,卻偏偏與公主長(zhǎng)得像今妄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354