nginx+lua+redis实现广告缓存 - 2021-09-17

一. 大致流程: client -- Openresty  -- Nginx -- lua -- redis -- mysql:

二. 环境:  linux虚拟机中安装: lua, openresty, nginx

1.lua

lua安装: 
yum install -y gcc
yum install libtermcap-devel ncurses-devel libevent-devel readline-devel
curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz
tar -zxf lua-5.3.5.tar.gz
cd lua-5.3.5​
make linux test​
make install

2. 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

 3. 默认已经安装好了nginx,在目录:/usr/local/openresty/nginx 

 三. 配置文件:

1. 修改/usr/local/openresty/nginx/conf/nginx.conf ,将配置文件使用的根设置为root, 使用lua脚本时 ,直接加载在root下的lua脚本

#user nobody; 配置文件第一行原来为这样, 现改为下面的配置
user root root;

 2. 配置/root目录下的lua脚本:

        (1). 创建ad_load.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 position = uri_args["position"]

local db = mysql:new()
db:set_timeout(1000)  
local props = {  
    host = "192.168.200.128",  
    port = 3306,  
    database = "changgou_business",  
    user = "root",  
    password = "root"  
}  

local res = db:connect(props)  
local select_sql = "select url,image from tb_ad where status ='1' and position='"..position.."' and start_time<= NOW() AND end_time>= NOW()"  
res = db:query(select_sql)  
db:close()  

local redis = require("resty.redis")
local red = redis:new()
red:set_timeout(2000)

local ip ="192.168.200.128"
local port = 6379
red:connect(ip,port)

red:set("ad_"..position,cjson.encode(res))
red:close()

ngx.say("{\"flag\":true,\"position\":\""..position.."\"}")

         (2). 创建ad_read.lua, 通过lua脚本直接从redis中获取数据

--设置响应头类型
ngx.header.content_type="application/json;charset=utf8"
--获取请求中的参数ID
local uri_args = ngx.req.get_uri_args();
local position = uri_args["position"];

--获取本地缓存
local cache_ngx = ngx.shared.dis_cache;
--根据ID 获取本地缓存数据
local adCache = cache_ngx:get('ad_cache_'..position);

if adCache == "" or adCache == nil then

--引入redis库
local redis = require("resty.redis");
--创建redis对象
local red = redis:new()
--设置超时时间
red:set_timeout(2000)
--连接
local ok, err = red:connect("192.168.200.128", 6379)
--获取key的值
local rescontent=red:get("ad_"..position)
--输出到返回响应中
ngx.say(rescontent)
--关闭连接
red:close()
--将redis中获取到的数据存入nginx本地缓存
cache_ngx:set('ad_cache_'..position, rescontent, 10*60);

else
 --nginx本地缓存中获取到数据直接输出
 ngx.say(adCache)
end

  (3). 修改/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;
    #包含redis初始化模块
    lua_shared_dict dis_cache 5m;  #共享内存开
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    # 设置限流配置
    limit_req_zone $binary_remote_addr zone=myRateLimit:10m rate=2r/s;

    server {
        listen       80;
        server_name  localhost;
        charset utf-8;
        #access_log  logs/host.access.log  main;
        # 添加
        location /ad_update {
            content_by_lua_file /root/lua/ad_update.lua;
        }
	# 读取
        location /ad_read {
            content_by_lua_file /root/lua/ad_read.lua;
        }

        
        # redirect server error pages to the static page /50x.html
        #
        #error_page   500 502 503 504  /50x.html;
        location = / {
            limit_req zone=myRateLimit burst=5 nodelay;
            root   html;
            index index.html index.htm;
        }        
    }
}

四. 报错:  redis读取不到缓存

        原因: 没有缓存预热, 预加载数据

​
测试:  先访问连接缓存预热  http://host/ad_update?position=web_index_lb
请求:  /ad_update
参数:  position  --指定广告位置
返回值:json
​

你可能感兴趣的:(日常Java基础BUG,lua,redis)