好好学习,天天向上
本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航
首页广告介绍
流程
在商城的首页,我们会看到很多广告,而很多时候这些广告内容都是固定的,所以每次访问MySQL获取广告内容效率是非常低的,比较好的做法就是用Redis和OpenResty做多级缓存。如果缓存中有数据就访问缓存,没有的话再去MySQL中获取,可以大大提高性能。
表结构
广告的数据是存放在changgou-content数据库中(我的这份资料里面没有这个数据库,我就自己创建了一个)。里面有两张表,一张是tb_content_catrgory(广告分类表),根据页面的不同位置,广告有不同的分类,比如首页轮播,猜你喜欢等;另一张是tb_content(广告表),这张表里存放了广告的数据。
CREATE TABLE `tb_content_category` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '类目ID',
`name` VARCHAR(50) DEFAULT NULL COMMENT '分类名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='内容分类';
INSERT INTO `tb_content_category` VALUES (1, '首页轮播广告');
INSERT INTO `tb_content_category` VALUES (2, '今日推荐A');
INSERT INTO `tb_content_category` VALUES (3, '活动专区');
INSERT INTO `tb_content_category` VALUES (4, '猜你喜欢');
CREATE TABLE `tb_content` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`category_id` BIGINT(20) NOT NULL COMMENT '内容类目ID',
`title` VARCHAR(200) DEFAULT NULL COMMENT '内容标题',
`url` VARCHAR(500) DEFAULT NULL COMMENT '链接',
`pic` VARCHAR(300) DEFAULT NULL COMMENT '图片绝对路径',
`status` VARCHAR(1) DEFAULT NULL COMMENT '状态,0无效,1有效',
`sort_order` INT(11) DEFAULT NULL COMMENT '排序',
PRIMARY KEY (`id`),
KEY `category_id` (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
INSERT INTO `tb_content` VALUES (1, 1, '微信广告', 'https://blog.csdn.net/weixin_43461520', 'https://gitee.com/RobodLee/image_store/raw/master/%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7.png', '1', 1);
Lua
简介
Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
安装
cd /usr/local/server # 切换到想要下载的目录,随意
curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz # 下载Lua5.3.5
tar zxf lua-5.3.5.tar.gz # 解压
cd lua-5.3.5 # 切换到解压后的目录
make linux test # 安装
-------------------------------------------------------------------------------------
[root@localhost lua-5.3.5]# lua # 输入lua,出现下面一行说明安装成功
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
编程方式
Lua有交互式编程和脚本式编程两种方式。
交互式编程
交互式编程是输入lua命令后进入到lua控制台,然后输入lua命令来执行。
[root@localhost lua-5.3.5]# lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print("Hello World!")
Hello World!
>
脚本式编程
脚本式编程就是创建一个.lua文件,然后输入命令“lua filename.lua”来执行。
基本语法
参考菜鸟教程Lua
OpenResty
简介
OpenResty 是一个强大的 Web 应用服务器,Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,更主要的是在性能方面,OpenResty可以快速构造出足以胜任 10K 以上并发连接响应的超高性能 Web 应用系统。就是封装了Nginx,并且集成了Lua脚本,开发人员只需要简单地使用提供的模块就可以实现相关的逻辑,而不再像之前,还需要在nginx中自己编写lua的脚本,再进行调用了。
安装
yum install yum-utils # 安装yum-utils,为了使用下面一行的命令
# 添加openresty的仓库,不配置这一行安装不了
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
yum install openresty # 安装openresty,界面会有提示,一路按y就可以了
安装完成之后,不要忘了启动
service openresty start
启动完成之后,用浏览器访问安装了openresty的虚拟机,如果出现了欢迎界面就说明安装成功了。
配置
虽然现在已经可以访问到OpenResty了,但是为了能够直接加载到root目录下的lua脚本,还需要配置一下。
cd /usr/local/openresty/nginx/conf # 切换到openresty安装目录下的nginx目录中的conf目录中
vi nginx.conf #编辑nginx的配置文件
广告缓存的载入与读取
本节的任务就是:Nginx拦截http://192.168.31.200/read_content?id=1,执行Lua脚本,先从Nginx缓存中加载,没有的话就从Redis中加载,再没有的话就从MySQL中加载,然后MySQL——>Redis——>Nginx——>浏览器。
定义Nginx缓存模块
cd /usr/local/openresty/nginx/conf # nginx的配置目录
vi nginx.conf # 编辑nginx的配置文件
在http里面配置Nginx的缓存模块:
Lua脚本
然后,准备好lua脚本,在root/lua目录下创建一个read_content.lua文件,填入以下内容:
ngx.header.content_type="application/json;charset=utf8"
local uri_args = ngx.req.get_uri_args(); -- 获取uri中的所有参数
local id = uri_args["id"]; -- 获取名为id的参数
--获取本地缓存
local cache_ngx = ngx.shared.dis_cache; -- 加载Nginx缓存模块,需要先定义
--根据ID 获取本地缓存数据
local contentCache = cache_ngx:get('content_cache_'..id);
--[[
Nginx中有缓存就输出缓存,没有的话就从Redis中加载
--]]
if contentCache == "" or contentCache == nil then
local redis = require("resty.redis"); -- 依赖Redis模块
local red = redis:new() -- 创建Redis对象
red:set_timeout(2000) -- 超时
red:connect("192.168.31.200", 6379) -- 连接Redis
local rescontent=red:get("content_"..id); -- 从Redis中读数据
-- Redis中没有就从MySQL中加载
if ngx.null == rescontent then
local cjson = require("cjson"); -- 依赖json模块
local mysql = require("resty.mysql"); -- 依赖mysql模块
local db = mysql:new(); -- 创建mysql对象
db:set_timeout(2000) -- 设置过期时间
-- mysql的参数信息
local props = {
host = "192.168.31.200",
port = 3306,
database = "changgou_content",
user = "root",
password = "root"
}
local res = db:connect(props); -- 连接mysql
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); --执行sql
local responsejson = cjson.encode(res); -- 将mysql返回的数据转换成json
red:set("content_"..id,responsejson); -- 存到Redis中
ngx.say(responsejson); -- 输出
db:close() -- 关闭mysql连接
else
cache_ngx:set('content_cache_'..id, rescontent, 10*60); -- 把Redis中的数据写到Nginx缓存中,设置过期时间
ngx.say(rescontent) -- 输出
end
red:close() -- 关闭Redis连接
else
ngx.say(contentCache) -- 输出
end
配置Nginx
现在需要配置一下nginx,让它能够执行该脚本。编辑上面提到的nginx.conf文件,在http.server中添加图中内容