前情描述:
由于我們在實(shí)際開發(fā)過程中伯诬,有些數(shù)據(jù)需要被頻繁讀取,而且這些數(shù)據(jù)基本不會被改變织盼,只會被頻繁查詢杨何,但是問題在于,我們的數(shù)據(jù)庫訪問承受能力是有限的沥邻,在訪問量非常高時(shí)危虱,數(shù)據(jù)庫負(fù)荷非常大,為了解決這個(gè)問題唐全,我們就可以用到OpenResty+redis+mysql埃跷。
思路解析:
OpenResty已經(jīng)內(nèi)置了nginx,所以我們實(shí)際上是通過訪問nginx來實(shí)現(xiàn)獲取數(shù)據(jù)邮利,nginx還可以起到其他的作用弥雹,這個(gè)以后在記錄⊙咏欤回歸正題剪勿,我們設(shè)想設(shè)計(jì)一個(gè)三級緩存來減輕數(shù)據(jù)庫的負(fù)荷,第一級緩存就是我們nginx的緩存方庭,第二級緩存就是redis的數(shù)據(jù)厕吉,第三級緩存就是數(shù)據(jù)庫的數(shù)據(jù)。當(dāng)我們發(fā)送請求獲取數(shù)據(jù)時(shí)械念,首先從nginx中獲取緩存數(shù)據(jù)赴涵,如果沒有,則從redis獲取订讼,redis也沒有髓窜,則從數(shù)據(jù)庫獲取,這里要注意一點(diǎn)欺殿,我們獲取到數(shù)據(jù)后寄纵,要把數(shù)據(jù)存到上一級緩存,這樣可以避免每次都要從下一級緩存獲取數(shù)據(jù)脖苏。
舉個(gè)例子:
如果我們的數(shù)據(jù)是從數(shù)據(jù)庫獲取的程拭,那我們再把數(shù)據(jù)給到前端時(shí),切記同時(shí)把數(shù)據(jù)存到redis和nginx緩存棍潘,不然我們的三級緩存就是去意義了恃鞋。
具體實(shí)現(xiàn):
我們使用lua腳本來實(shí)現(xiàn)對mysql數(shù)據(jù)庫和redis的操作(lua的基本語法大家可以自己再網(wǎng)上找找崖媚,應(yīng)該有很多)
1.修改/usr/local/openresty/nginx/conf/nginx.conf,將配置文件使用的根設(shè)置為root,目的就是將來要使用lua腳本的時(shí)候 ,直接可以加載在root下的lua腳本
命令:
cd /usr/local/openresty/nginx/conf
vi nginx.conf
2.定義lua緩存命名空間畅哑,修改nginx.conf,添加如下代碼即可
添加lua_shared_dict dis_cache 128m
3.創(chuàng)建一個(gè)文件到 /root/lua/read.lua水由,編寫lua代碼
ngx.header.content_type="application/json;charset=utf8"local uri_args = ngx.req.get_uri_args();local id = uri_args["id"];
--獲取本地緩存
local cache_ngx = ngx.shared.dis_cache;
--根據(jù)ID 獲取本地緩存數(shù)據(jù)
local contentCache = cache_ngx:get('content_cache_'..id);
if contentCache == "" or contentCache == nil then
? ? local redis = require("resty.redis");
? ? local red = redis:new()
? ? red:set_timeout(2000)
? ? red:connect("192.168.211.132", 6379)
? ? local rescontent=red:get("content_"..id)
--如果nginx沒有數(shù)據(jù)荠呐,則從數(shù)據(jù)庫查找
if ngx.null == rescontent then
? ? ? ? local cjson = require("cjson");
? ? ? ? local mysql = require("resty.mysql");
? ? ? ? local db = mysql:new();
? ? ? ? db:set_timeout(2000)
? ? ? ? local props = {
? ? ? ? ? ? host = "192.168.72.110",
? ? ? ? ? ? port = 3306,
? ? ? ? ? ? database = "data",
? ? ? ? ? ? user = "root",
? ? ? ? ? ? password = "root"
? ? ? ?}
? ? ? ?local res = db:connect(props);
? ? ? ?local select_sql = "select * from user";
? ? ? ?res = db:query(select_sql);
? ? ? ?local responsejson = cjson.encode(res);
? ? ? ?red:set("content_"..id,responsejson);
? ? ? ?ngx.say(responsejson);
? ? ? ?db:close()
? ? else
--將數(shù)據(jù)存到nginx緩存
? ? ? ?cache_ngx:set('content_cache_'..id, rescontent, 10*60);
? ? ? ?ngx.say(rescontent);
? ? end
? ? red:close()
else
? ? ngx.say(contentCache)
end
4.設(shè)置訪問路徑,修改nginx配置文件如下
5.訪問:http://nginx的所在ip地址/read_content
拿到數(shù)據(jù)砂客,測試成功