Nginx框架之Lua拓展
目录
Lua脚本简述
Lua脚本简述
脚本特点
安装Lua
lua小例子
Nginx增加Lua执行模块
Nginx嵌入Lua脚本语言
Nginx嵌入Lua脚本语言
ngx_lua支持的指令
在OpenResty中演示ngx_lua的指令
打造高性能后端接口
OpenResty Redis模块
OpenResty mysql模块
OpenResty http模块
Lua模板渲染器
使用
Nginx非阻塞与Lua协程的绝配
Lua协程
Nginx的API生成页面
Lua脚本简述
nginx三大核心功能,包含静态资源、反向代理、api模块扩展,对于lua脚本的扩展,就是api模块扩展的一部分;并且nginx可以通过lua脚本直接调用redis服务器;
Lua脚本简述
lua官网:
The Programming Language Lua
应用在图像处理这些。
- 1. 许多工业应用 (例如, Adobe的Photoshop Lightroom)
- 2. 重点是嵌入式系统(例如, 巴西的数字电视的 Ginga中间件)
- 3. Lua目前 是游戏中领先的脚本语言,在游戏 (例如, 魔兽世界和愤怒的小鸟)中使用。
脚本特点
- 快,Lua是解释脚本语言领域中最快的语言。
- Lua是便携式的,在具有标准C编译器的所有平台中构建成开箱即用,可运行各种Unix和Windows, 移动设备(运行Android,iOS,BREW,Symbian,Windows Phone),嵌入式微处理器(如ARM和Rabbit,适用于Lego MindStorms等应用程序),IBM大型机等。
- 可嵌入,Lua是一种快速语言引擎,占用空间小,可以轻松嵌入到应用程序中。
- 简单而强大,提供实现功能的*元机制*,而不是直接在语言中提供大量功能。Lua不是纯粹的面对 象语言,提供了实现类和继承的元机制。
- 小,源包含大约24000行C,包含源代码和文档的Lua 5.3.5的tar包需要297K压缩和1.2M未压缩。 免费,MIT许可证,可以用于任何目的,包括商业目的,完全免费。
比js语言更加广泛。轻量级语言不能做的事情,没有什么大的框架,例如java中spring,这也是它其中的一个缺点把
安装Lua
比较简单
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
依赖不多,直接下载就行。
使用打印 hello world
$ lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print("hello, world")
hello, world
lua小例子
- 定义一个外界可见的表
- 受保护的自定义数据内容
- function给_M定义一个方法,get_age,用来返回data中的数据
- 向外界暴露表
-- 定义一个外界可见的表
local _M = {}-- 受保护的自定义数据内容
local data = {dog = 5,cat = 3,pig = 1,
}-- function给_M定义一个方法,get_age,用来返回data中的数据
function _M.get_age(name)return data[name]
end -- end表示方法结束-- 向外界暴露表
return _M
这个和js中的方法就很像了。
利用lua脚本实现 阶乘
-- defines a factorial function
function fact (n)
if n == 0 then
return 1
else
return n * fact(n-1)
end
end
print("enter a number:")
a = io.read("*number") -- read a number
print(fact(a))
要运行 ,直接 使用 lua 文件就能运行起来
语法比Java要简略,缩进对齐,无大括号分号
Nginx增加Lua执行模块
Nginx嵌入Lua脚本语言
ngx_lua模块
Nginx嵌入Lua脚本语言
安装编译Nginx
- 安装依赖项
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel# lua_jit
wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
tar -xvf LuaJIT-2.0.5.tar.gz
cd LuaJIT-2.0.5
make install
下载安装nginx和依赖项
cd ~
# nginx
wget http://nginx.org/download/nginx-1.14.2.tar.gz
tar -xvf nginx-1.14.2.tar.gz
# ndk
wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.0.zip
unzip v0.3.0.zip
# ngx_lua 模块
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.14.zip
unzip v0.10.14.zip# 安装nginx
cd nginx-1.14.2
./configure --prefix=/usr/local/nginx-1.14.2 \--add-module=../ngx_devel_kit-0.3.0 \--add-module=../lua-nginx-module-0.10.14
- 测试lua模块是否安装成功
- 创建一个文件夹存储lua脚本
mkdir /usr/local/nginx-1.14.2/lua_scripts
- 创建mydata.lua
-- mydata.lualocal _M = {}local data = {dog = 3,cat = 4,pig = 5,}function _M.get_age(name)return data[name]endreturn _M
- nginx.conf文件
lua_package_path "/usr/local/nginx-1.14.2/lua_scripts/?.lua;;";server {...location /lua {content_by_lua_block {local mydata = require "mydata"ngx.say(mydata.get_age("dog"))}}
可能的错误
# 1、动态库找不到
./sbin/nginx: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory
# 解决办法:
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig# 2、warn提示
nginx: [alert] detected a LuaJIT version which is not OpenResty's; many optimizations will be disabled and performance will be compromised (see https://github.com/openresty/luajit2 for OpenResty's LuaJIT or, even better, consider using the OpenResty releases from https://openresty.org/en/download.html)
# 告诉你,你不要用这个luajit版本,可以用openresty提供的luajit优化版本,或者干脆直接用openresty
安装lua_redis
wget https://codeload.github.com/openresty/lua-resty-redis/zip/master
unzip master
cd lua-resty-redis-master
make && make install
都是lua集成的组件。
OpenResty 目录
包括nginx目录等。
ngx_lua支持的指令
指令分为配置指令、控制指令。
控制指令分为两种方式:
lua脚本块*_by_lua_block
lua脚本文件*_by_lua_file
Lua脚本执行顺序,如右图从上至下:初始化、重写/访问、内容处理、日志输出四个阶段。
在OpenResty中演示ngx_lua的指令
设置由set_by_lua,content_by_lua等指定的脚本使用的Lua模块搜索路径。类似java的classPath
预加载json模块
在location、location if上下文中使用。充当“内容处理程序”并执行指定的lua脚本内容,Lua代码可以进行API调用,并在独立的全局环境(即沙箱)中作为新的衍生协程执行
worker_processes 1;
events {worker_connections 1024;
}http {# 设置由set_by_lua, content_by_lua等指定的脚本使用的Lua模块搜索路径。类似java的classPath# 路径字符串采用标准的Lua路径形式,;; 可用于代表原始搜索路径。lua_package_path "/usr/local/openresty/lua_scripts/?.lua;;";# 申请一个名为dogs的10m字典内存,共享在所有工作进程中lua_shared_dict dogs 10m;# 在服务器启动时预加载Lua模块,并利用现代操作系统的写时复制(COW)优化。init_by_lua_block {-- 预加载json模块require "cjson"-- 操作共享内存local dogs = ngx.shared.dogs;dogs:set("Tom", 56)}server {listen 8080;location /lua {default_type text/html;# 在location、location if上下文中使用。充当“内容处理程序”并执行指定的lua脚本内容,# Lua代码可以进行API调用,并在独立的全局环境(即沙箱)中作为新的衍生协程执行content_by_lua_block {local mydata = require "mydata"ngx.say(mydata.get_age("dog"))-- require关键字会返回init_by_lua_block中已经预加载了cjson模块ngx.say(require "cjson".encode{dog = 5, cat = 6})-- 读取共享内存中的信息local dogs = ngx.shared.dogs;ngx.say(dogs:get("Tom"))}}}
}
在运行的时候,需要去掉 nginx目录在运行
打造高性能后端接口
OpenResty Redis模块
要使用Redis非常简单
-- 引入Redis模块
local redis = require("resty.redis")
--创建实例
local red = redis:new()
--建立连接
local ok, err = red:connect(“127.0.0.1”, 6379)
--调用API进行处理
ok, err = red:set("msg", "hello world")
local resp, err = red:get("msg")
这里 用local进行申请变量。 这是lua脚本 和js语言基本一致的地方。
这个模块要保证在linux上客户端存在redis,然后运行lua脚本。
在OpenResty 中 lualib /resty 中放在 这个目录下面的
- 在写lua脚本时需要引用 默认就是 lualib
local redis = require("resty.redis")
- 创建实例 建立连接,通过new方式
--创建实例
local red = redis:new()
--设置超时(毫秒)
red:set_timeout(1000)
--建立连接
local ip = "127.0.0.1"
local port = 6379
local ok, err = red:connect(ip, port)
- 发送数据并判断是否成功
if not ok then ngx.say("connect to redis error : ", err) return close_redis(red)
end
--调用API进行处理
ok, err = red:set("msg", "hello world")
if not ok then ngx.say("set msg error : ", err) return close_redis(red)
end
- 关闭redis
local function close_redis(red) if not red then return end --释放连接(Redis连接池实现)local pool_max_idle_time = 10000 --毫秒 local pool_size = 100 --连接池大小 local ok, err = red:set_keepalive(pool_max_idle_time, pool_size) if not ok thenngx.say("set keepalive error : ", err)end
end
- 得到的数据为空处理
--得到的数据为空处理
if resp == ngx.null then resp = '' --比如默认值
end
ngx.say("msg : ", resp) close_redis(red)
对于redis操作,lua脚本是没有事务的支持的。
在 nginx_lua_lib.conf配置上对应的location
请求得到数据
使用场景
降低tomcat的压力,非常有用的。根据不会走到web服务器上。 增大请求这些,是构建百万连接的重要一部分
OpenResty mysql模块
也是一样的 加载 mysql的驱动
local mysql = require("resty.mysql")
创建实例
local db, err = mysql:new() if not db then ngx.say("new mysql error : ", err) return end
设置超时时间(毫秒)
db:set_timeout(1000)
配置建立连接
local props = { host = "127.0.0.1", port = 3306, database = "mysql", user = "root", password = "123456" } local res, err, errno, sqlstate = db:connect(props) if not res then ngx.say("connect to mysql error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end
删除表
local drop_table_sql = "drop table if exists test" res, err, errno, sqlstate = db:query(drop_table_sql) if not res then ngx.say("drop table error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end
创建表
local create_table_sql = "create table test(id int primary key auto_increment, ch varchar(100))" res, err, errno, sqlstate = db:query(create_table_sql) if not res then ngx.say("create table error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end
关闭连接
local function close_db(db) if not db then return end db:close() end
这里有个点安全机制,防止sql注入
--防止sql注入 local ch_param = ngx.req.get_uri_args()["ch"] or '' --使用ngx.quote_sql_str防止sql注入 local query_sql = "select id, ch from test where ch = " .. ngx.quote_sql_str(ch_param) res, err, errno, sqlstate = db:query(query_sql) if not res then ngx.say("select error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end for i, row in ipairs(res) do for name, value in pairs(row) do ngx.say("select row ", i, " : ", name, " = ", value, "<br/>") end end
OpenResty http模块
OpenResty默认没有提供Http客户端,需要使用第三方提供,从github上搜索相应的客户端,比如lua-resty-http
cd /usr/local/openresty/lualib/resty/
sudo wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http_headers.lua
sudo wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http.lua
这个模块可以调用第三方的服务。
local http = require("resty.http")
--创建http客户端实例
local httpc = http.new()local resp, err = httpc:request_uri("http://www.baidu.com", { method = "GET", path = "/s?wd=123",headers = {["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36" }
}) if not resp then ngx.say("request error :", err) return
end --获取状态码
ngx.status = resp.status --获取响应头
for k, v in pairs(resp.headers) do if k ~= "Transfer-Encoding" and k ~= "Connection" then ngx.header[k] = v end
end
--响应体
ngx.say(resp.body)httpc:close()
Lua模板渲染器
动态web网页开发是Web开发中一个常见的场景,Lua中也有许多模板引擎,我们通过lua-resty-template来完成动态页面的渲染。
cd /usr/local/openresty/lualib/resty/
wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template.lua
mkdir /usr/local/openresty/lualib/resty/html
cd /usr/local/openresty/lualib/resty/html
wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template/html.lua
动态生成网页模板。
使用
nginx配置文件,添加模板解析路径
#首先匹配nginx下面的模板目录
set $template_location "/templates";
#然后匹配指定的模板根目录,我们这里是/usr/local/openresty/lua_scripts
set $template_root "/usr/local/openresty/lua_scripts";
#或者通过root指令来切换路径
root /usr/local/openresty/lua_scripts;
lua内容,html_template.lua
local template = require("resty.template") local context = { title = "lua模板渲染", name = "hash同学", description = "<script>alert(1);</script>", age = 20, hobby = {"电影", "音乐", "阅读"}, score = {语文 = 90, 数学 = 80, 英语 = 70}, score2 = { {name = "语文", score = 90}, {name = "数学", score = 80}, {name = "英语", score = 70}, }
}
template.render("resty_template.html", context)
进行解析生成模板。
Nginx非阻塞与Lua协程的绝配
-- foo本身是个协程,由nginx调用
function foo()
-- 此处由nginx发起db的连接请求,因为异步这里先暂停协程
users = db.query('users', {name: name});
-- 当请求有响应得到处理时,继续执行协程,这些才运行
deal_with(users);
end
Lua协程
coroutine.create(f)
创建一个新的协同程序并返回一个类型为thread的对象,并不启动协程。
coroutine.resume(co)
开始或继续执行协同程序co
coroutine.yield
暂停执行调用协程,让出CPU
coroutine.wrap(f)
类似create方法,创建一个协程但它不是返回协程本身,而是返回一个函数,当被调用时,它恢复协程
Nginx的API生成页面
达到对一个商品页面的实现。
Nginx框架之Lua拓展相关推荐
- CentOS6.4 安装OpenResty和Redis 并在Nginx中利用lua简单读取Redis数据
1.下载OpenResty和Redis OpenResty下载地址:wget http://openresty.org/download/ngx_openresty-1.4.3.6.tar.gz Re ...
- nginx整合php+lua+oracle环境搭建
nginx整合php+lua+oracle环境搭建 标签: nginxluaoraclephplinux 2014-09-25 10:39 1473人阅读 评论(0) 收藏 举报 分类: 技术( ...
- Linux守护进程的创建(结合nginx框架)
Linux守护进程的创建(结合nginx框架) 先介绍几个相关函数: int dup2(arg1,arg2):参数一指向的内容赋给参数二,shi的参数二也能访问参数一所指向的内容,并返回新的描述符 i ...
- 无线专题 openwrt feeds、web框架luci(lua语言)、UCI (统一配置接口)
1.openwrt feeds UCI (统一配置接口)openwrt官方说明(有中文版本):https://oldwiki.archive.openwrt.org/zh-cn/doc/uci 在Op ...
- Nginx安装配置Lua支持
Nginx安装配置Lua支持 1. 环境准备 2. 下载最新的`luajit`和`ngx_devel_kit`以及`lua-nginx-module`解压 3. 解压`ngx_devel_kit`以及 ...
- nginx lua连接mysql_OpenResty的安装和在nginx中使用lua直接访问mysql达到数据接口的统一...
OpenResty 它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. 如果需要nginx的第三方库的时候,可以考虑OpenResty,可以少掉很多安装的麻烦,Open ...
- nginx redis mysql_Nginx + Lua + Kafka + Redis + Mysql
写在开头 # 系统版本 cat /etc/issue CentOS release 6.8 (Final) # 切换到tmp目录 cd /tmp 安装 lua # 下载 wget http://lua ...
- nginx.conf添加lua.conf配置
1.在nginx的conf下配置lua.conf......vi lua.conf server { listen 80; server_name _;location /lua { default_ ...
- Unity3D 基于XLua框架实现Lua组件化开发方式(一)----基于C#调用Lua
众所周知Unity的开发语言是C#,并不支持Lua语言,为了解决这一问题出现了诸如Xlua.ULua.ToLua等框架来让unity支持lua,由于为了应对众多游戏经常需要解决的热更新问题,出了两种主 ...
- fastdfs+nginx+keepalived+openoffice+lua 实现文件上传、下载、水印、预览(word、excel、ppt、txt),feign文件上传
前言 最近刚刚实现的文件服务中心,记录一下,为没做过的人提供一下思路,由于本人技术有限,不足之处欢迎批评指正,共同学习,共同进步. 目录 Fastdfs集群搭建 搭建keepalived 实现ngxi ...
最新文章
- postgresql 比较两个时间差大于 N个小时
- 进制转换(洛谷-P1017)
- matlab中怎么表示概率,[转载]matlab中的概率函数
- 海量数据处理相关算法及数据结构【转】
- Multisim14简介与安装
- 1041 例题4-2 比较交换实数值
- 一个如何在bash中使用getopts的例子
- 美团:后端开发工程师(实习生)面试
- Mac上常用软件-2018
- twitter三方登录的实现
- 庆祝JavaCard技术领导SmartCard技术超过五年
- Eloquent JavaScript 笔记 九: Regular Expressions(下)
- @media媒体查询——详解
- 已知三角形三个顶点求内切圆和外接圆半径 以及面积 C语言模板
- matlab 播放声音,Matlab:实时播放音频并显示波形
- 深圳图高智能深耕5G三防夜视智能终端细分领域,引领行业发展
- 三相永磁同步电机(PMSM) SVPWM矢量控制 MATLA 仿真算法
- 东南大学计算机学研招生人数,东南大学2020硕士研究生各专业报录比汇总(实考人数:录取人数)...
- 三相整流器移相触发电路的整体FPGA设计
- linux 帐户安全管理员权限,Linux系统账号安全控制
热门文章
- NoSQLBooster for MongoDB 算法注册机
- 互联网日报 | 4月5日 星期一 | 华为首款台式显示器登陆海外;腾讯视频VIP会员4月10日起涨价;我国民宿房源超300万套...
- 洛谷P4563 [JXOI2018]守卫
- 2021中国科技大学计算机博士招生,中国科学技术大学2021年拟录取博士研究生名单公示,2661人!...
- linux下gpt分区,Linux下的GPT分区
- 百度热力图颜色说明_揭秘!张家口100万人口热力图,看完你就知道房子该买哪里了...
- 关于计算机教学的论文,关于计算机教学论文.docx
- 迅雷下载太慢怎么办?
- 树莓派(4B)入门教程
- ssm框架搭建连接mysql_搭建SSM框架(一) - xiaoqi__y的个人空间 - OSCHINA - 中文开源技术交流社区...