一、OpenResty介紹
OpenResty(又稱:ngx_openresty) 是一個基于 nginx的可伸縮的 Web 平台,由中國人章亦春發起,提供了很多高品質的第三方子產品。
OpenResty 是一個強大的 Web 應用伺服器,Web 開發人員可以使用 Lua 腳本語言調動 Nginx 支援的各種 C 以及 Lua 子產品,更主要的是在性能方面,OpenResty可以 快速構造出足以勝任 10K 以上并發連接配接響應的超高性能 Web 應用系統。
360,UPYUN,阿裡雲,新浪,騰訊網,去哪兒網,酷狗音樂等都是 OpenResty 的深度使用者。
OpenResty 簡單了解成 就相當于封裝了nginx,并且內建了LUA腳本,開發人員隻需要簡單的其提供了子產品就可以實作相關的邏輯,而不再像之前,還需要在nginx中自己編寫lua的腳本,再進行調用了。
安裝openresty
linux安裝openresty:
1.添加倉庫執行指令
安裝nginx
預設已經安裝好了nginx,在目錄:/usr/local/openresty/nginx 下。
修改/usr/local/openresty/nginx/conf/nginx.conf,将配置檔案使用的根設定為root,目的就是将來要使用lua腳本的時候 ,直接可以加載在root下的lua腳本。
二、廣告緩存的載入與讀取
需求分析
需要在頁面上顯示廣告的資訊。
解決方法 Lua+Nginx配置
(1)實作思路-查詢資料放入redis中
實作思路:
定義請求:用于查詢資料庫中的資料更新到redis中。
a.連接配接mysql ,按照廣告分類ID讀取廣告清單,轉換為json字元串。
b.連接配接redis,将廣告清單json字元串存入redis 。
定義請求:
請求位址: http://192.168.xxx.xxx/update_content?id=1 建立/root/lua目錄,在該目錄下建立update_content.lua: 目的就是連接配接mysql 查詢資料 并存儲到redis中。 修改/usr/local/openresty/nginx/conf/nginx.conf檔案: 添加頭資訊,和 location資訊 定義lua緩存命名空間,修改nginx.conf,添加如下代碼即可: 請求可以實作緩存的添加
(2)實作思路-從redis中擷取資料
定義請求,使用者根據廣告分類的ID 擷取廣告的清單。通過lua腳本直接從redis中擷取資料即可。
請求:/read_content
參數:id
傳回值:json
在/root/lua目錄下建立read_content.lua:
在/usr/local/openresty/nginx/conf/nginx.conf中配置如下:(3)加入openresty本地緩存
如上的方式沒有問題,但是如果請求都到redis,redis壓力也很大,是以我們一般采用多級緩存的方式來減少下遊系統的服務壓力。參考基本思路圖的實作。
先查詢openresty本地緩存 如果 沒有
再查詢redis中的資料,如果沒有
再查詢mysql中的資料,但凡有資料 則傳回即可。
修改read_content.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;
--根據ID 擷取本地緩存資料
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);
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.211.132",
port = 3306,
database = "xxx_content",
user = "root",
password = "123456"
}
local res = db:connect(props);
local select_sql = "select url,pic from tb_content where status ='1' and category_id="..id.." order by sort_order";
res = db:query(select_sql);
local responsejson = cjson.encode(res);
red:set("content_"..id,responsejson);
ngx.say(responsejson);
db:close()
else
cache_ngx:set('content_cache_'..id, rescontent, 10*60);
ngx.say(rescontent)
end
red:close()
else
ngx.say(contentCache)
end
測試位址:
http://192.168.211.132/update_content?id=1此時會将分類ID=1的所有廣告查詢出來,并存入到Redis緩存。
http://192.168.xxx.xxx/read_content?id=1此時會擷取分類ID=1的所有廣告資訊。