- Nginx_Lua
- 1.1.소개
- 1.2.
- 1.2.1. JIT 플랫폼 설치
- 1.2.2. NDK 및 Lua_module
- 1.2.3 Nginx
- 1.3 Lua 삽입 후.
- 1.3.1. 탐지 버전
- 1.3.2. Hello, World
- 1.3.3. 동기식, 비동기식 실행
- 1.4. Nginx 및 Lua 실행 순서
- 1.4.1.Nginx 순서
- 1.4.2.Lua 순서
- Lua 기본 구문
- 2.1. 키워드
- 2.2.
- 2.2.1.수치연산
- 2.2.2.대입연산
- 2.2.3.논리연산
2.3. 조건부 판단문
2.3.1.if- 2.3.2.반복
- 2.3.3.
-
- 2.4.
2.4.1.테이블2.4.2.루아 테이블 빈 판단-
- 2.5. 🎜>
- 1. Nginx_Lua
1.1.소개
ngx_lua - nginx Logic 기반의 비즈니스를 빠르게 개발할 수 있도록 lua 언어를 nginx에 내장합니다.
이 모듈은 nginx 소스 코드 패키지에 포함되어 있지 않으므로 직접 다운로드, 컴파일 및 설치해야 합니다. lua 5.1(lua 5.2는 현재 지원되지 않음) 또는 luajit 2.0을 사용하세요.
Lua 지원을 추가한 후에도 복잡한 모듈의 개발이 빠르고 여전히 100% 비동기식이며 논블로킹입니다.
ngx_lua 사용 대상:
Taobao, Tencent Finance, NetEase Finance, 360, Qunar.com 등
CloudFlare, CNN, Wingify, Reblaze, Turner, Broadcasting 시스템
이 프로젝트의 주요 개발자:
chaoslawful Taobao, Alibaba Grp.
agentzh CloudFlare
https://github.com/chaoslawful/lua - nginx 모듈
1.2. 설치
1.2.1. JIT 플랫폼 설치
JIT
LuaJIT
通常,程序有两种运行方式:静态编译与动态直译。
静态编译的程序在执行前全部被翻译为机器码,而动态直译执行的则是一句一句边运行边翻译。
即时编译(Just-In-Time Compiler)则混合了这二者,一句一句编译源代码,但是会将翻译过的代码缓存起来以降低性能损耗。
JAVA、.NET 实现都使用即时编译以提供高速的代码执行。
注意:
在nginx.conf中添加"lua_code_cache on/off",来开启是否将代码缓存,所以每次变更"*.lua"文件时,必须reload nginx才可生效。
仅针对"set_by_lua_file, content_by_lua_file, rewrite_by_lua_file, and access_by_lua_file"有效, 因为其他为写在配置文件
中,更改代码也必须reload nginx。在生产环境下,不能禁用cache。同时在lua代码中使用"dofile" 或 "loadfie" 来加载外部lua脚步
将不会对它进行缓存,应该使用"require"来代替。禁用cache,当且仅当在调式代码下。
demo 1NDK 및 Lua_module
NDK(Nginx 개발 키트)를 다운로드하고 컴파일합니다. ) 모듈 Nginx 서버의 핵심 기능을 확장한 모듈입니다是一个利用JIT编译技术把Lua脚本直接编译成机器码由CPU运行
版本:2.0 与 2.1
当前稳定版本为 2.0。
2.1为版本与ngx_lua将有较大性能提升,主要是CloudFlare公司对luajit的捐赠。
FFI库,是LuaJIT中最重要的一个扩展库。
1. 它允许从纯Lua代码调用外部C函数,使用C数据结构;
2. 就不用再像Lua标准math库一样,编写Lua扩展库;
3. 把开发者从开发Lua扩展C库(语言/功能绑定库)的繁重工作中释放出来;
demo 2이를 기반으로 타사 모듈 개발을 빠르게 구현할 수 있습니다NDK는 몇 가지 기본 작업을 처리할 수 있는 기능과 매크로를 제공하며, 타사 모듈 개발을 위한 코드 양을 줄입니다.
wget -c http://luajit.org/download/LuaJIT-2.0.2.tar.gz
tar xzvf LuaJIT-2.0.2.tar.gz
cd LuaJIT-2.0.2
make install PREFIX=/usr/local/luajit
echo "/usr/local/luajit/lib" > /etc/ld.so.conf.d/usr_local_luajit_lib.conf
ldconfig
#注意环境变量!
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.01.2.3. Nginx 컴파일 및 설치
1.3. Lua 삽입 후1.3.1. 🎜 >1.3.2. Hello, Worldwget -c https://github.com/simpl/ngx_devel_kit/archive/v0.2.18.tar.gz
wget -c https://github.com/chaoslawful/lua-nginx-module/archive/v0.8.6.tar.gz
tar xzvf v0.2.18
tar xzvf v0.8.6nginx.conf의 서비스에 위치를 추가합니다. wget -c http://nginx.org/download/nginx-1.4.2.tar.gz
tar xzvf nginx-1.4.2.tar.gz
cd nginx-1.4.2
./configure --add-module=../ngx_devel_kit-0.2.18/ --add-module=../lua-nginx-module-0.8.6/
make
make install데모 4
http://localhost/test에 액세스하는 사용자는 "Hello World" 콘텐츠를 인쇄합니다.
自己编译官方的 nginx 源码包,只需事前指定 LUAJIT_INC 和 LUAJIT_LIB 这两个环境变量。
验证你的 LuaJIT 是否生效,可以通过下面这个接口:
location = /lua-version {
content_by_lua '
if jit then
ngx.say(jit.version)
else
ngx.say(_VERSION)
end
';
}
demo 3
如果使用的是标准 Lua,访问 /lua-version 应当返回响应体 Lua 5.1
如果是 LuaJIT 则应当返回类似 LuaJIT 2.0.2 这样的输出。
不要使用标准lua,应当使用luajit, 后者的效率比前者高多了。
也可以直接用 ldd 命令验证是否链了 libluajit-5.1 这样的 .so 文件,例如:
[root@limq5 sbin]# ldd nginx | grep lua
libluajit-5.1.so.2 => /usr/local/luajit/lib/libluajit-5.1.so.2 (0x00007f48e408b000)
[root@limq5 sbin]#ngx.say는 Lua가 모듈에 노출하는 인터페이스입니다. 마찬가지로 error.log에 디버깅 정보를 출력할 수 있는 ngx.log(ngx.DEBUG, "")가 있습니다. 또한 외부 스크립트도 호출할 수 있습니다. php 및 jsp 애플리케이션을 작성할 때와 마찬가지로 비즈니스 스크립트는 .php 또는 .jsp 파일로 별도로 구성됩니다.
location = /test {
content_by_lua '
ngx.say("Hello World")
ngx.log(ngx.ERR, "err err err")
';
} File hello.lua의 내용은 다음과 같습니다.
여기의 스크립트는 임의로 복잡할 수도 있고 Lua 자체 라이브러리를 사용할 수도 있습니다.
lua에 사용 가능한 모듈 목록 :
http:/ /luarocks.org/repositories/rocks/
location = /test2 {
content_by_lua_file conf/lua/hello.lua;
}설치는 yum과 유사하며 창고도 있습니다:luarocks install luafilesystem
위 명령 "lfs.so"를 실행한 후 nginx에서 정의한 LUA_PATH에 파일을 복사한 다음 ngx.say("Hello World") 라이브러리를 참조하여 해당 함수를 호출합니다.
LUA_PATH:
lua_package_path '/opt/17173/nginx-ds/conf/lua/?.lua;;'
lua_package_cpath '/opt/17173/nginx- ds/conf/lua/lib/?.so;/usr/local/lib/?.?;;';
여기서 ";;"는 원래 검색 범위를 나타냅니다.
데모 5
1.3.3. 동기식, 비동기식 실행
여러 데이터 소스에 동시에 액세스해야 하며 쿼리에 종속성이 없다고 가정합니다. , 그러면 동시에 요청을 실행할 수 있습니다
이런 방식으로 총 지연 시간은 모든 원래 요청 시간을 중첩하는 것이 아니라 모든 요청 중 가장 느린 요청에 걸린 시간입니다
1.4.Nginx 및 Lua 실행 순서
1.4.1 Nginx 순서
Nginx는 각 사용자 요청을 여러 단계에 따라 순차적으로 처리합니다. (단계), 구성 파일의 순서를 따르지 않습니다.
Nginx 요청 처리 과정은 11단계로 구분됩니다. 실행 순서는
post-read, server-rewrite, find-config, rewrite, post-rewrite, preaccess, access입니다. , 사후 액세스, 시도 파일, 콘텐츠, 로그.
location = /api {
content_by_lua '
local res1, res2, res3 =
ngx.location.capture_multi{
{"/memc"}, {"/mysql"}, {"/postgres"}
}
ngx.say(res1.body, res2.body, res3.body)
';
}
demo 6ngx.location.capture 无法跨server进行处理, 只能在同一个server下的不同location。
Taobao에서 유용한 정보가 많이 포함된 nginx 개발 매뉴얼을 공개했습니다. post-read:
读取请求内容阶段
Nginx读取并解析完请求头之后就立即开始运行
例如模块 ngx_realip 就在 post-read 阶段注册了处理程序,它的功能是迫使 Nginx 认为当前请求的来源地址是指定的某一个请求头的值。server-rewrite
Server请求地址重写阶段
当 ngx_rewrite 模块的set配置指令直接书写在 server 配置块中时,基本上都是运行在 server-rewrite 阶段http://tengine.taobao.org/book/find-config
配置查找阶段
这个阶段并不支持 Nginx 模块注册处理程序,而是由 Nginx 核心来完成当前请求与 location 配置块之间的配对工作。rewrite
Location请求地址重写阶段
当 ngx_rewrite 模块的指令用于 location 块中时,便是运行在这个 rewrite 阶段。
另外,ngx_set_misc(设置md5、encode_base64等) 模块的指令,还有 ngx_lua 模块的 set_by_lua 指令和 rewrite_by_lua 指令也在此阶段。저자의 Google 포럼: post-rewrite
请求地址重写提交阶段
由 Nginx 核心完成 rewrite 阶段所要求的“内部跳转”操作,如果 rewrite 阶段有此要求的话。 preaccess
访问权限检查准备阶段
标准模块 ngx_limit_req 和 ngx_limit_zone 就运行在此阶段,前者可以控制请求的访问频度,而后者可以限制访问的并发度。https://groups.google.com/forum/#!forum/openrestyaccess
访问权限检查阶段
标准模块 ngx_access、第三方模块 ngx_auth_request 以及第三方模块 ngx_lua 的 access_by_lua 指令就运行在这个阶段。
配置指令多是执行访问控制性质的任务,比如检查用户的访问权限,检查用户的来源 IP 地址是否合法post-access
访问权限检查提交阶段
主要用于配合 access 阶段实现标准 ngx_http_core 模块提供的配置指令 satisfy 的功能。
satisfy all(与关系)
satisfy any(或关系)1.4.2. Lua 시퀀스try-files
配置项try_files处理阶段
专门用于实现标准配置指令 try_files 的功能
如果前 N-1 个参数所对应的文件系统对象都不存在,try-files 阶段就会立即发起“内部跳转”到最后一个参数(即第 N 个参数)所指定的 URI.content
内容产生阶段
Nginx 的 content 阶段是所有请求处理阶段中最为重要的一个,因为运行在这个阶段的配置指令一般都肩负着生成“内容”
并输出 HTTP 响应的使命。log
日志模块处理阶段
记录日志Nginx에서의 Lua 처리 단계 및 사용 범위 : 공식 문서를 참고하세요:
http://wiki.nginx.org/HttpLuaModule
2. 구문
2.1. 키워드
2.2. 연산init_by_lua http
set_by_lua server, server if, location, location if
rewrite_by_lua http, server, location, location if
access_by_lua http, server, location, location if
content_by_lua location, location if
header_filter_by_lua http, server, location, location if
body_filter_by_lua http, server, location, location if
log_by_lua http, server, location, location if
timerinit_by_lua:
在nginx重新加载配置文件时,运行里面lua脚本,常用于全局变量的申请。
例如lua_shared_dict共享内存的申请,只有当nginx重起后,共享内存数据才清空,这常用于统计。
set_by_lua:
设置一个变量,常用与计算一个逻辑,然后返回结果
该阶段不能运行Output API、Control API、Subrequest API、Cosocket API
rewrite_by_lua:
在access阶段前运行,主要用于rewrite
access_by_lua:
主要用于访问控制,能收集到大部分变量,类似status需要在log阶段才有。
这条指令运行于nginx access阶段的末尾,因此总是在 allow 和 deny 这样的指令之后运行,虽然它们同属 access 阶段。
content_by_lua:
阶段是所有请求处理阶段中最为重要的一个,运行在这个阶段的配置指令一般都肩负着生成内容(content)并输出HTTP响应。
header_filter_by_lua:
一般只用于设置Cookie和Headers等
该阶段不能运行Output API、Control API、Subrequest API、Cosocket API
body_filter_by_lua:
一般会在一次请求中被调用多次, 因为这是实现基于 HTTP 1.1 chunked 编码的所谓“流式输出”的。
该阶段不能运行Output API、Control API、Subrequest API、Cosocket API
log_by_lua:
该阶段总是运行在请求结束的时候,用于请求的后续操作,如在共享内存中进行统计数据,如果要高精确的数据统计,应该使用body_filter_by_lua。
该阶段不能运行Output API、Control API、Subrequest API、Cosocket API
timer:2.2.1. 숫자 연산2.2.2. 🎜>
2.2.3.논리연산
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while2.3.조건부 판단문2.3.1. >2.3.2 .반복支持 +, -, *, /,^ 比如2^3 结果为8, 2^4结果为16。
连接两个字符串,用".."运处符, php为".", JAVA、C#为"+"2.3.3.a,b,c,d=1,2,3,4 -- 多变量一起赋值
a,b=b,a --交换变量功能
在默认情况下,变量总是认为是全局的。假如需要定义局部变量,则在第一次赋值的时候,需要用local说明。比如:
local a,b,c = 1,2,3 -- a,b,c都是局部变量2.3.4.and, or, not
在Lua中,只有false和nil才计算为false,其它任何数据都计算为true,0也是true
and 和 or的运算结果不是true和false,而是和它的两个操作数相关。
a and b:如果a为false,则返回a;a true 返回b
a or b:如果 a 为true,则返回a;a false 返回b2.4. 模拟C语言中的语句:x = a? b : c,在Lua中,可以写成:x = a and b or c。
最有用的语句是: x = x or v,它相当于:if not x then x = v end 。2.4.1.테이블
;예시 1if 条件 then
...
elseif 条件 then
... else ...
end;예시 2repeat ... until 条件2.4.2. 공허한 판단while 条件
do
...
end프로젝트 스크립트 lua에 이런 요구사항이 있는 경우가 많습니다for 变量=初值, 终点值, 步进
do
...
endfor 变量1, 变量2, ... 变量n in 表或枚举函数
do
...
end2.5. 참고1. table 是 lua 中最重要的数据类型。
2. table 类似于 python 中的字典。
3. table 只能通过构造式来创建
이상으로 Ngx_Lua의 사용과 공유에 대해 내용적인 측면을 포함하여 소개하였습니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.