解決方案:OpenResty 網站首頁資料快取
需求: 將網站首頁進行獨立部署到Nginx中
實作的思路 : Nginx+Lua(OpenResty成熟的產品)
一、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.添加倉庫執行命令
yum install yum-utils
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
2.執行安裝
yum install openresty
3.安裝成功后 會在默認的目錄如下:
/usr/local/openresty
安裝nginx
默認已經安裝好了nginx,在目錄:/usr/local/openresty/nginx 下
修改/usr/local/openresty/nginx/conf/nginx.conf ,將組態檔使用的根設定為root,目的就是將來要使用lua腳本的時候 ,直接可以加載在root下的lua腳本,
#user nobody; 組態檔第一行原來為這樣, 現改為下面的配置
user root root;
測驗訪問 http://47.103.77.82/

二、首頁資料快取實作思路
快取預熱與二級快取查詢
步驟一: 撰寫lua腳本實作快取預熱(將mysql里的資料查詢出來存入redis)
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DVDWQBp5-1630565924386)(七、網站首頁高可用解決方案.assets/image-20210804195557591.png)]](https://img.uj5u.com/2021/09/03/261333031838033.png)
步驟二: 撰寫lua腳本實作二級快取讀取
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qeft4T6v-1630565924388)(七、網站首頁高可用解決方案.assets/image-20210804195620359.png)]](https://img.uj5u.com/2021/09/03/261333031838031.png)
快取預熱
實作思路:
定義請求:用于查詢資料庫中的資料更新到redis中,
(1)連接mysql ,讀取資料串列,轉換為json字串,
(2)連接redis,將資料串列json字串存入redis ,
在/root/lua目錄下創建data_update.lua ,實作連接mysql 查詢資料 并存盤到redis中,
ngx.header.content_type="application/json;charset=utf8"
local cjson = require("cjson")
local mysql = require("resty.mysql")
local uri_args = ngx.req.get_uri_args()
local db = mysql:new()
db:set_timeout(1000)
local props = {
host = "ip地址",
port = 3306,
database = "dabing_business",
user = "用戶名",
password = "密碼"
}
local res = db:connect(props)
local select_sql = "select * from tb_data "
res = db:query(select_sql)
db:close()
local redis = require("resty.redis")
local red = redis:new()
red:set_timeout(2000)
local ip ="ip地址"
local port = 6379
red:connect(ip,port)
red:set("ad_"..data,cjson.encode(res))
red:close()
ngx.say("{\"flag\":true,\"data\":\""..data.."\"}")
通過http可以訪問上述的腳本:
? 修改/usr/local/openresty/nginx/conf/nginx.conf檔案:
代碼如下:
#user nobody;
user root root;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
charset utf-8;
# access_log logs/host.access.log main;
# 添加,通過http可以訪問上述的腳本
location /ad_update {
content_by_lua_file /root/lua/data_update.lua;
}
# redirect server error pages to the static page/50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
重新啟動nginx
測驗:http://IP地址/data_update
快取讀取
實作思路:
定義請求,用戶根據廣告分類的ID 獲取廣告的串列,通過lua腳本直接從redis中獲取資料即可,
定義請求:
請求:/data_read
引數:position
回傳值:json
在/root/lua目錄下創建data_read.lua
--設定回應頭型別
ngx.header.content_type="application/json;charset=utf8"
--獲取請求中的引數ID
local uri_args = ngx.req.get_uri_args();
--引入redis庫
local redis = require("resty.redis");
--創建redis物件
local red = redis:new()
--設定超時時間
red:set_timeout(2000)
--連接
local ok, err = red:connect("IP地址", 6379)
--獲取key的值
local rescontent=red:get("ad_"..data)
--輸出到回傳回應中
ngx.say(rescontent)
--關閉連接
red:close()
在/usr/local/openresty/nginx/conf/nginx.conf中server下添加配置
location /data_read {
content_by_lua_file /root/lua/data_read.lua;
}
測驗 http://IP地址/ad_read
加入openresty本地快取
如上的方式沒有問題,但是如果請求都到redis,redis壓力也很大,所以我們一般采用多級快取的方式來減少下游系統的服務壓力,
先查詢openresty本地快取 如果沒有再查詢redis中的資料
-
修改/root/lua目錄下data_read檔案, 內容如下:
--設定回應頭型別 ngx.header.content_type="application/json;charset=utf8" --獲取請求中的引數ID local uri_args = ngx.req.get_uri_args(); --獲取本地快取 local cache_ngx = ngx.shared.dis_cache; --根據ID 獲取本地快取資料 local dataCache = cache_ngx:get('data_cache_'); -----------------------略 --將redis中獲取到的資料存入nginx本地快取 cache_ngx:set('data_cache_', rescontent, 10*60); else --nginx本地快取中獲取到資料直接輸出 ngx.say(dataCache) end可以手動清理本地快取:
-
my_cache : flush_all(),這是不釋放記憶體,而是標記過期,
-
my_cache : flush_expired(),清除過期,最多清除可選引數
-
max_count,如果不指定引數或者指定引數為0,不設限制,
修改nginx組態檔vi /usr/local/openresty/nginx/conf/nginx.conf ,http節點下添加配置:
#包含redis初始化模塊 lua_shared_dict dis_cache 5m; #共享記憶體開啟在快取中沒有資料的時候,可以撰寫相應提示
--將redis中獲取到的資料存入nginx本地快取 local succ,err = cache_ngx:set('data_cache_', rescontent, 10*60); if not succ then ngx.say("set faile ,err:"..err.."建議增加本地共享記憶體空間"); end -
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/297111.html
標籤:其他
