电商项目-网站首页高可用(二)

一、LUA基本语法

lua有交互式编程和脚本式编程。

交互式编程就是直接输入语法,就能执行。

脚本式编程需要编写脚本文件,然后再执行。

一般采用脚本式编程。(例如:编写一个hello.lua的文件,输入文件内容,并执行lua hell.lua即可)

1.1.1 lua注释注释

单行注释:两个减号是单行注释:

Lua 复制代码
--

多行注释:

Lua 复制代码
--[[
 多行注释
 多行注释
 --]]
1.1.2关键字

关键字就好比java中的 break if else等等一样的效果。lua的关键字如下:

and break do else
elseif end false for
function if in local
nil not or repeat
return then true until
while
1.1.3 定义变量

全局变量,默认的情况下,定义一个变量都是全局变量,

如果要用局部变量 需要声明为local.例如:

Lua 复制代码
-- 全局变量赋值
a=1
-- 局部变量赋值
local b=2 

如果变量没有初始化:则 它的值为nil 这和java中的null不同。

1.1.4 Lua中的数据类型

Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。

Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。

数据类型 描述
nil 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。
boolean 包含两个值:false和true。
number 表示双精度类型的实浮点数
string 字符串由一对双引号或单引号来表示
function 由 C 或 Lua 编写的函数
userdata 表示任意存储在变量中的C数据结构
thread 表示执行的独立线路,用于执行协同程序
table Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。
1.1.5 流程控制

如下:类似于if else

Lua 复制代码
--[ 0 为 true ]
if(0) then
    print("0 为 true")
else
    print("0 不为true")
end
1.1.6 函数

lua中也可以定义函数,类似于java中的方法。例如:

Lua 复制代码
--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)
​
   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end
​
   return result; 
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))

执行之后的结果:

Lua 复制代码
两值比较最大值为     10
两值比较最大值为     6
1.1.7 require 函数

require 用于 引入其他的模块,类似于java中的类要引用别的类的效果。

用法:

Lua 复制代码
require "<模块名>"

二、nginx+Lua+redis实现广告缓存

2.1 表结构分析

操作shangcheng_business 数据库的 tb_ad (广告表)

字段名称 字段含义 字段类型 字段长度 备注
id ID INT
name 广告名称 VARCHAR
position 广告位置 VARCHAR 系统定义
start_time 开始时间 DATETIME
end_time 到期时间 DATETIME
status 状态 CHAR 0:无效 1:有效
image 图片地址 VARCHAR
url URL VARCHAR
remarks 备注 VARCHAR
web_index_lb 首页轮播图
web_index_amusing 有趣区
web_index_ea_lb 家用电器楼层轮播图
web_index_ea 家用电器楼层广告
web_index_mobile_lb 手机通讯楼层轮播图
web_index_mobile 手机通讯楼层广告
2.2 缓存预热与二级缓存查询

步骤一:编写lua脚本实现缓存预热(将mysql里的数据查询出来存入redis)

步骤二:编写lua脚本实现二级缓存读取

2.3.1 缓存预热

实现步骤:

定义请求:用于查询数据库中的数据更新到redis中。

(1)连接mysql ,按照广告分类ID读取广告列表,转换为json字符串。

(2)连接redis,将广告列表json字符串存入redis 。

定义请求:

Lua 复制代码
请求:
    /ad_update
参数:
    position  --指定广告位置
返回值:
    json

步骤一:在/root/lua目录下创建ad_load.lua ,实现连接mysql 查询数据 并存储到redis中。

步骤二:修改/usr/local/openresty/nginx/conf/nginx.conf文件:

代码如下:

Lua 复制代码
#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;
        # 添加
        location /ad_update {
            content_by_lua_file /root/lua/ad_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;
        }        
    }
}

3)测试

重新启动nginx

测试:http://192.168.200.128/ad_update?position=web_index_lb

查看redis客户端

2.3.2 广告缓存读取

实现步骤:

通过lua脚本直接从redis中获取数据即可。

定义请求:

Lua 复制代码
请求:/ad_read
参数:position
返回值:json

1)在/root/lua目录下创建ad_read.lua

2)在/usr/local/openresty/nginx/conf/nginx.conf中server下添加配置

Lua 复制代码
location /ad_read {
  content_by_lua_file /root/lua/ad_read.lua;
}

3)测试

测试 http://192.168.200.128/ad_read?position=web_index_lb 输出:

javascript 复制代码
[{"url":"img\/banner1.jpg","image":"img\/banner1.jpg"},
{"url":"img\/banner2.jpg","image":"img\/banner2.jpg"}]
2.4 二级缓存(openresty本地缓存)

如上的方式没有问题,但是如果请求都到redis,redis压力也很大,所以我们一般采用多级缓存的方式来减少下游系统的服务压力。

先查询openresty本地缓存 如果没有再查询redis中的数据

1)修改/root/lua目录下ad_read文件, 内容如下:

2)修改nginx配置文件vi /usr/local/openresty/nginx/conf/nginx.conf ,http节点下添加配置:

Lua 复制代码
#包含redis初始化模块
lua_shared_dict dis_cache 5m;  #共享内存开启
2.5前端页面实现

(1)修改index.html,编写脚本

javascript 复制代码
<script>
       new Vue({
        el: '#app',
        data: {
            ad: {
                web_index_lb:[]
            }
        },
        methods: {
            adRead: function(position) {
                axios.get('ad_read?position='+position).then(response =>{
                    this.ad[position]=response.data                 
                })
            }
        },
        created(){
            this.adRead('web_index_lb')
        }
      })
</script>

(2)修改index.html,渲染广告轮播图

html 复制代码
<div id="myCarousel" data-ride="carousel" data-interval="4000" class="sui-carousel slide">
    <ol class="carousel-indicators">
        <li data-target="#myCarousel" data-slide-to="0" class="active" v-for="item in ad.web_index_lb"></li>
    </ol>
    <div class="carousel-inner" id="lbt">
        <div class="item" v-for="item in contentList">
            <a :href="item.url">
            <img :src="item.pic"  />
          </a>
        </div>      
    </div>
    <a href="#myCarousel" data-slide="prev" class="carousel-control left">‹</a>
    <a href="#myCarousel" data-slide="next" class="carousel-control right">›</a>
</div>

(3)上传至服务器并测试

更改配置:

Lua 复制代码
# 加载首页
        location / {
            root   html;
            index  index.html index.htm;
        }
相关推荐
一直都在5726 小时前
Redis (一)
数据库·redis·缓存
秦jh_7 小时前
【Redis】客户端使用
数据库·redis·缓存
随风,奔跑8 小时前
Redis
数据库·redis·缓存
TlYf NTLE9 小时前
redis分页查询
数据库·redis·缓存
大萌神Nagato10 小时前
力扣HOT100 Q146LRU缓存
算法·leetcode·缓存
鬼蛟10 小时前
Redis
数据库·redis·缓存
8Qi811 小时前
Redis哨兵模式(Sentinel)深度解析
java·数据库·redis·分布式·缓存·sentinel
CDN36012 小时前
CDN 缓存命中率低如何提升?忽略参数与规则设置教程
运维·缓存
M--Y13 小时前
初识Redis
数据库·redis·缓存
皙然14 小时前
Redis核心理论:数据删除与淘汰策略详解(从原理到实战)
数据库·redis·缓存