该技术不仅仅是应用于, 广告缓存 只是常用于做广告的缓存!
对于一个应用来多,每天都会有很多的用户来访问, 那么访问最多的就是首页了!
而对于首页这种,高访问,且 页面数据并不是,经常的变化!
为了减轻服务器的压力,直接将其制作成一个 静态的页面进行展示!
编程语言的特性
if else逻辑判断,访问数据库 redis; 它只是一个负载均衡器;
所以,需要通过lua 嵌入式语言
来完成
c 作为底层语言,写的东西都快!
其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。内置了大量开发好的,脚本文件 mysql redis....
(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
实现数组,哈希表,集合,对象
通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等游戏开发,独立应用脚本,Web 应用脚本,扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench
并不需要安装,windows 只需要配置一下系统的环境变量即可: 环境变量也只是为了可以在系统的任意对方可以使用!
Path: D:\WSMwork\lua
(本人的安装路径
**lua53 或 lua53 -i **都可以启动lua
print("输出内容!");
print("hello");
执行命令:lua53 文件名.lua
直接输入语法,就能直接执行
。
并执行lua53 hell.lua即可
)
lua53 不同版本的lua 执行要指定版本号!
创建 .lua文件, 进行执行...
hello.lua
-- 单行注释
--[[
多行注释
多行注释
]]--
同Java 一样有,全局变量和局部变量:
hello.lua
-- 全局变量赋值
a=1
-- 局部变量赋值
local b=2
-- ..拼接
print(a..b)
print(a..':'..b)
a='张三'
字符可以使用,单引号 或 双引号来表示,utf-8可能会乱码,建议文件编码 ANSl
如果变量没有初始化:则 它的值为nil 这和java中的null不同。
数值运算还是通过 + - * /
type( 值 ) 返回值的类型
print(type("Hello world")) --> string
print(type(10.4*3)) --> number 包含double int
print(type(print)) --> function
print(type(type)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
类似于Orcal的存储过程!
-- 条件括号,可选:加或不加
if(布尔表达式)then
--[ 在布尔表达式为 true 时执行的语句 --]
end
if——else
if(布尔表达式)then
--[ 布尔表达式为 true 时执行该语句块 --]
else
--[ 布尔表达式为 false 时执行该语句块 --]
end
if——esleif——elseif——else——end
local age =15
if (age>=18) then
print('成年人')
elseif age<18 then
print('未成年')
else
print('未出生')
end
while(条件true执行)do
print(‘执行循环内容…’)
end
for var=exp1,exp2,exp3 do
print(‘执行循环内容…’)
end
--[[
var 从 exp1 变化到 exp2
每次变化以 exp3 为步长递增 var 并执行一次 “执行体”。
exp3 是可选的,如果不指定,默认为1。
]]--
repeat 无论如何都会执行一次until 条件成立true
则结束循环!repeat
print(‘执行循环内容…’)
until( true退出循环 )
--[[ 函数返回两个值的最大值 --]]
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))
执行之后的结果:
table
-- 初始化表mytable = {}
-- 指定值mytable[1]= "Lua"
-- 移除引用mytable = nil
table={}
table[0]="张三1"
table[1]="张三2"
table[2]="张三3"
--table 是一个对象
print(table)
--通过下标来获取值
print(table[0])
--table = nil 来清空表/对象
table = nui
print(table)
print(table[0])
模块定义
模块管理机制
,可以把一些公用的代码放在一个文件里;
以 API 接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度。module.lua
别忘了中文乱码,文件格式设置ASCII码
module.lua
-- 文件名为 module.lua
-- 定义一个名为 module 的模块,和文件名一样!
module = {}
-- 定义一个常量
module.constant = "这是一个常量"
-- 定义一个函数 module.func1
function module.func1()
print("这是一个公有函数")
end
-- 定义一个局部(私有) 方法
-- 因此是不能从外部访问模块里的这个私有函数,必须通过模块里的公有函数来调用
local function func2()
print("这是一个私有函数!")
end
-- 模拟调用私有方法...
function module.func3()
func2()
end
return module
require
用于引入其他的模块,类似于java中的类要引用别的类的效果。
要引入的模块,要放在一个文件夹下,可以是子文件!不然找不到!
require("<模块名>")
-- 或
require "<模块名>"
编程特性
由 OpenResty 团队自主开发)
OpenResty下载D:\WSMwork\openresty-1.15.8.2-win64\lualib\resty 路径下包含了很多的lua 模块
配置lua库位置:修改openresty-1.15.8.2-win64\conf\nginx.conf
文件
接下来的大部分操作都是在: 自定义的lua.conf文件中执行
自定义的lua.conf
#给nginx 分内存 128m 兆 缓存大小!用于存放热点数据(频繁使用的数据!)
lua_shared_dict my_cache 128m;
#nginx服务
server {
listen 9090; #指定端口9090,默认80
server_name _;
#静态模板地址设置...
set $template_location "/templates";
set $template_root "D:/templates"; #填写对应的地址...
#nginx分流的请求路径...
location /mylua{
default_type text/html;
#通过 content_by_lua_block{ lua的执行代码 } ngx.say('是lua的浏览器输出方法!')
content_by_lua_block{
local age = 20
if age>=18 then
ngx.say('>=18');
else
ngx.say('<18');
end
}
}
}
lua的执行操作就写在这里
是nginx拥有了编程语言的特性!
OpenResty1.9.3.2以前是 content_by_lua{ } 可通过 nginx -v
查看版本号!就像Java的 Out打印流一样!
OpenResty目录下 cmd
没有异常就是执行成功!
刷新
命令当修改了文件,频繁调用 nginx.exe是启动,开启进行造成堵塞!正确的方法是刷新,重启
OpenResty目录下 cmd
nginx端口占用,启动报错:bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a …)
nginx.conf文件下还有默认的 80端口启动.. 可能会与电脑里某个端口冲突, 直接更改即可!
或者:停止进程 Windows操作!
netstat -aon | findstr :80
80表示端口
tasklist|findstr "进程号"
在nginx 配置中写lua 代码不方便书写,可以直接在外面写好,调用即可!
location /mylua2{
default_type text/html;
content_by_lua_file D:/WSMwork/myweb.lua;
}
#content_by_lua_file 引入外部的lua文件, 分号结尾;
引入外部的.lua 文件
外部文件~
刷新nginx
这样就需要nginx需要有发起http请求的能力
myweb.lua
--设置编码格式!
ngx.header.content_type="text/html;charset=utf8"
--调用ngx 模块中的方法,返回请求url
local uri_args = ngx.req.get_uri_args()
--获取请求参数!
local zz = uri_args["zz"]
--获取http 模块,require( );
local http = require("resty.http")
--http模块 new( ) 一个httpc对象
local httpc = http.new()
--..拼接参数 wd
local resp = httpc:request_uri("http://127.0.0.1:9002/info/hello/"..zz,{
method = "GET", --get请求;
keepalive=false --无论如何都请求;
})
--返回参结果,打印结果!
local val = resp.body
ngx.say(val)
注意这里的参数是在 nginx,9090端口的请求参数!
就是这个lua模块负载发送请求, OpenResty 中存在着很多的,lua脚本模块…
跟get 非常类似…
ngx.req.read_body() --获取请求url
local arg = ngx.req.get_post_args() --参数集合 Map类型!
--声明几个用于存储的空对象
id=nil
deptname=nil
--循环参数集合!
for k,v in pairs(arg) do
--判断参数,key 进行参数赋值!
if k=="id" then
id = v
end
if k=="deptname" then
deptname = v
end
end
--页面输出!
ngx.say("deptname: ", deptname)
ngx.say("id: ", id)
myweb.lua
-- 定义私有方法
local function close_redis(red)
if not red then
return
end
-- 释放连接(连接池实现),毫秒
local pool_max_idle_time = 10000
-- 连接池大小
local pool_size = 100
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
local log = ngx_log
if not ok then
log(ngx_ERR, "set redis keepalive error : ", err)
end
end
-- 连接redis
local redis = require('resty.redis') --引入模块
local red = redis.new()
red:set_timeout(1000)
local ip = "127.0.0.1"
local port = "6379"
-- local pwd= "ok" 本人没有密码直接注释!
-- 连接测试 ip 端口是否正确...
ok, err = red:connect(ip,port)
if not ok then
ngx.say("failed to auth: ", err)
return close_redis(red)
end
-- 密码是否正确 没有密码直接注释!
--[[
ok, err = red:auth(pwd)
if not ok then
ngx.say("failed to auth: ", err)
return close_redis(red)
end
]]--
--获取redis第一个库,redis一共16给库
red:select('0')
red:set("msg","test ngx hello") --set存入一个msg key,值:test ngx hello
-- get根据key查找... 并处理异常
local resp, err = red:get("msg")
if not resp then
ngx.say("get msg error : ", err)
return close_redis(red)
end
--打印关闭资源!
ngx.say("msg : ", resp)
close_redis(red)
安装目录下:redis-server.exe
直接网关请求!
既然要数据库操作,那么就搞个数据库吧!mysql
myweb.lua
--创建连接mysql模块
local mysql = require "resty.mysql"
-- connect to mysql;
local db, err = mysql:new()
if not db then
return false --没连上关闭!
end
--超时时间
db:set_timeout(1000)
--设置连接信息
local ok, err, errno, sqlstate = db:connect{
host = "127.0.0.1", --ip
port = 3306, --端口
database = "book", --连接的数据库
user = "root", --用户
password = "ok", --密码
max_packet_size = 1024 * 1024 --字节大小 1m
}
--验证是否连接上
if not ok then
ngx.say("connect mysql failed")
return false --没连上关闭
end
if db == false then
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
return
end
ngx.say("----------查询数据----------------","<br/>")
res, err, errcode, sqlstate =
db:query("SELECT * FROM bookinfo") --实际情况,可能还需要拼接参数....
--没有数据,返回...异常!
if not res then
ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
return
end
--获取JSON 模块
local cjson = require "cjson"
--JSON翻译,页面输出
ngx.say("result: ", cjson.encode(res))
--如果是新增...
--[[
--如果没有返回结果,新增异常提示!
if not res then
ngx.say("insert failed")
return
end
--返回影响行数
ngx.say("insert rows :", res.affected_rows,", id", res.insert_id, "<br/>")
]]--