Lua-Nginx-Module中哪些常用指令具体用法和配置细节?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1322个文字,预计阅读时间需要6分钟。
本章将介绍基于LuaJIT的Lua-Nginx-Module,它是Nginx的第三方开源软件,功能丰富,可轻松满足高并发的业务需求。请注意,本书使用的Lua-Nginx-Module版本是0.10.13。
本章将会讲解基于LuaJIT的Lua-Nginx-Module,它作为Nginx的第三方开源软件,拥有十分丰富的功能,可以轻松完成高并发的业务需求。注意:本书使用的Lua-Nginx-Module版本是0.10.13。Nginx API for Lua将被简称为Lua API,而Lua-Nginx-Module则被简称为Ngx_lua。后面章节中涉及到的Lua API大部分是包含参数的,如果参数以?结尾,代表这个参数是可选的,如在指令ngx.req.get_headers (max_headers?, raw?)中,max_headers和raw是可选的。
一、Nginx和OpenResty
首先,来认识一下OpenResty,它是一个基于Nginx和Lua开发的高性能的Web平台,包含大量成熟的第三方库,可快速搭建出高性能的Web服务器,支持常用的反向代理、网关系统、Web应用等。
如果在Nginx上使用Ngx_lua,需要先进行编译;而OpenResty已经包含此模块,不需要再进行编译了。读者可以自由选择使用Nginx或OpenResty来搭建服务,如果无法抉择,可参考如下场景。
- 使用Nginx编译Ngx_Lua的场景
HTTP代理服务器:复杂度较小,只需部分组件即可,且代理服务器一般由运维人员进行维护。使用Nginx的稳定版进行编译,在性能方面会更有保障,而OpenResty是Nginx的主线版,可能会不定期更新。
- OpenResty的使用场景
API服务:业务需求多,需要大量组件。
网关系统:需要大量组件和指令来实现动态组件功能。
Web应用服务器:业务服务、页面服务等,如详情页业务的开发。
使用Nginx编写的Lua代码都可以直接迁移到OpenResty上;反之却不一定可行,毕竟OpenResty的组件更多。
二、安装Ngx_lua
请先安装LuaJIT 2.1.0-beta3(详见第6.2节)并需要编译ngx_devel_kit模块。
下面是在Nginx上的安装方式(OpenResty自带此模块,不必安装编译):
# wget ‘nginx.org/download/nginx-1.12.2.tar.gz‘ # git clone github.com/simplresty/ngx_devel_kit.git # git clone github.com/openresty/lua-nginx-module.git # tar -xzvf nginx-1.12.2.tar.gz # cd nginx-1.12.2/ # ./configure --prefix=/usr/local/nginx_1.12.2 --add-module=../ngx_devel_kit --add-module=../lua-nginx-module --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" # make && make install
并不是每个Nginx版本都支持最新的Ngx_lua,目前已知支持最新Ngx_lua的Nginx版本如下:
1.13.x (last tested: 1.13.6) 1.12.x 1.11.x (last tested: 1.11.2) 1.10.x 1.9.x (last tested: 1.9.15) 1.8.x 1.7.x (last tested: 1.7.10) 1.6.x
如需获取最新版本的支持动态,请参考github.com/openresty/lua-nginx-module# nginx-compatibility。
三、牢记context标识
Ngx_lua API指令和Nginx的指令一样,都存在配置环境的约束问题,因此在使用过程中要确保指令的环境符合预期,例如:
ngx.var.VARIABLE
语法:ngx.var.VAR_NAME
context(配置环境):set_by_lua,rewrite_by_lua,access_by_lua,content_by_lua,header_ filter_by_lua,body_filter_by_lua,log_by_lua*
context即配置环境,第一次接触Ngx_lua的读者看到这样的配置环境可能会觉得难以理解,因为这还涉及到Ngx_Lua的执行阶段(后面会有介绍)。
四、Hello world
首先,还是来一条经典语句“Hello, world”,在Nginx配置中加入一个server:
server { listen 80; server_name testnginx.com; charset koi8-r; location = /test { #设置文件使用的默认MIME-type,将会增加一个Content-Type:text/plain的响应头 default_type ‘text/plain‘; -- content_by_lua_block执行阶段 content_by_lua_block { ngx.say(‘Hello,world!‘) } } }
访问这个server,输出如下:
# curl -I testnginx.com/test Hello,world!
ngx.say将数据作为响应体输出,返回给客户端,并在末尾加上一个回车符。
代码中用到了content_by_lua_block这个指令块,它的主要作用是在HTTP的内容处理阶段生成数据,详见第8.6节。
五、避免I/O阻塞
当Nginx和Lua进行读取磁盘操作时会对Nginx的事件循环造成阻塞,所以在请求中应尽量避免操作磁盘,特别是当文件较大时。
如果Lua使用网络I/O,为了避免出现阻塞的情况,请使用基于Lua API开发的指令,并使用子请求(将在7.13节介绍)来发送网络I/O和磁盘I/O。如果需要频繁读取磁盘,请分离磁盘I/O的任务和网络I/O的任务,避免它们相互影响。
六、定义模块搜索路径
在开发过程中,常常需要编写自定义的模块,或者引入第三方的Lua或C模块,通过下面的配置可以定义相关模块的路径以方便快速查找。
6.1 定义Lua模块的搜索路径
lua_package_path用来设置默认的Lua模块的搜索路径,并配置在testnginx.com/nginx/var.html?test=12132&a=2&b=c&dd‘ HTTP/1.1 200 OK Server: nginx/1.12.2 Date: Thu, 07 Jun 2018 07:22:32 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: keep-alive 1 curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2 12132 nginx
如果是未定义的Nginx变量,是无法直接在Lua中进行读取的。而且有些变量只能读取,无法进行修改,如$query_string、$arg_PARAMETER和$testnginx.com/test?=12132&a=2&b=c&dd‘ HTTP/1.1 200 OK Server: nginx/1.12.2 Date: Fri, 08 Jun 2018 07:46:38 GMT Content-Type: application/octet-stream Transfer-Encoding: chunked Connection: keep-alive Header name:host value: testnginx.com Header name:accept value: */* Header name:user-agent value: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2 testnginx.com
本文共计1322个文字,预计阅读时间需要6分钟。
本章将介绍基于LuaJIT的Lua-Nginx-Module,它是Nginx的第三方开源软件,功能丰富,可轻松满足高并发的业务需求。请注意,本书使用的Lua-Nginx-Module版本是0.10.13。
本章将会讲解基于LuaJIT的Lua-Nginx-Module,它作为Nginx的第三方开源软件,拥有十分丰富的功能,可以轻松完成高并发的业务需求。注意:本书使用的Lua-Nginx-Module版本是0.10.13。Nginx API for Lua将被简称为Lua API,而Lua-Nginx-Module则被简称为Ngx_lua。后面章节中涉及到的Lua API大部分是包含参数的,如果参数以?结尾,代表这个参数是可选的,如在指令ngx.req.get_headers (max_headers?, raw?)中,max_headers和raw是可选的。
一、Nginx和OpenResty
首先,来认识一下OpenResty,它是一个基于Nginx和Lua开发的高性能的Web平台,包含大量成熟的第三方库,可快速搭建出高性能的Web服务器,支持常用的反向代理、网关系统、Web应用等。
如果在Nginx上使用Ngx_lua,需要先进行编译;而OpenResty已经包含此模块,不需要再进行编译了。读者可以自由选择使用Nginx或OpenResty来搭建服务,如果无法抉择,可参考如下场景。
- 使用Nginx编译Ngx_Lua的场景
HTTP代理服务器:复杂度较小,只需部分组件即可,且代理服务器一般由运维人员进行维护。使用Nginx的稳定版进行编译,在性能方面会更有保障,而OpenResty是Nginx的主线版,可能会不定期更新。
- OpenResty的使用场景
API服务:业务需求多,需要大量组件。
网关系统:需要大量组件和指令来实现动态组件功能。
Web应用服务器:业务服务、页面服务等,如详情页业务的开发。
使用Nginx编写的Lua代码都可以直接迁移到OpenResty上;反之却不一定可行,毕竟OpenResty的组件更多。
二、安装Ngx_lua
请先安装LuaJIT 2.1.0-beta3(详见第6.2节)并需要编译ngx_devel_kit模块。
下面是在Nginx上的安装方式(OpenResty自带此模块,不必安装编译):
# wget ‘nginx.org/download/nginx-1.12.2.tar.gz‘ # git clone github.com/simplresty/ngx_devel_kit.git # git clone github.com/openresty/lua-nginx-module.git # tar -xzvf nginx-1.12.2.tar.gz # cd nginx-1.12.2/ # ./configure --prefix=/usr/local/nginx_1.12.2 --add-module=../ngx_devel_kit --add-module=../lua-nginx-module --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" # make && make install
并不是每个Nginx版本都支持最新的Ngx_lua,目前已知支持最新Ngx_lua的Nginx版本如下:
1.13.x (last tested: 1.13.6) 1.12.x 1.11.x (last tested: 1.11.2) 1.10.x 1.9.x (last tested: 1.9.15) 1.8.x 1.7.x (last tested: 1.7.10) 1.6.x
如需获取最新版本的支持动态,请参考github.com/openresty/lua-nginx-module# nginx-compatibility。
三、牢记context标识
Ngx_lua API指令和Nginx的指令一样,都存在配置环境的约束问题,因此在使用过程中要确保指令的环境符合预期,例如:
ngx.var.VARIABLE
语法:ngx.var.VAR_NAME
context(配置环境):set_by_lua,rewrite_by_lua,access_by_lua,content_by_lua,header_ filter_by_lua,body_filter_by_lua,log_by_lua*
context即配置环境,第一次接触Ngx_lua的读者看到这样的配置环境可能会觉得难以理解,因为这还涉及到Ngx_Lua的执行阶段(后面会有介绍)。
四、Hello world
首先,还是来一条经典语句“Hello, world”,在Nginx配置中加入一个server:
server { listen 80; server_name testnginx.com; charset koi8-r; location = /test { #设置文件使用的默认MIME-type,将会增加一个Content-Type:text/plain的响应头 default_type ‘text/plain‘; -- content_by_lua_block执行阶段 content_by_lua_block { ngx.say(‘Hello,world!‘) } } }
访问这个server,输出如下:
# curl -I testnginx.com/test Hello,world!
ngx.say将数据作为响应体输出,返回给客户端,并在末尾加上一个回车符。
代码中用到了content_by_lua_block这个指令块,它的主要作用是在HTTP的内容处理阶段生成数据,详见第8.6节。
五、避免I/O阻塞
当Nginx和Lua进行读取磁盘操作时会对Nginx的事件循环造成阻塞,所以在请求中应尽量避免操作磁盘,特别是当文件较大时。
如果Lua使用网络I/O,为了避免出现阻塞的情况,请使用基于Lua API开发的指令,并使用子请求(将在7.13节介绍)来发送网络I/O和磁盘I/O。如果需要频繁读取磁盘,请分离磁盘I/O的任务和网络I/O的任务,避免它们相互影响。
六、定义模块搜索路径
在开发过程中,常常需要编写自定义的模块,或者引入第三方的Lua或C模块,通过下面的配置可以定义相关模块的路径以方便快速查找。
6.1 定义Lua模块的搜索路径
lua_package_path用来设置默认的Lua模块的搜索路径,并配置在testnginx.com/nginx/var.html?test=12132&a=2&b=c&dd‘ HTTP/1.1 200 OK Server: nginx/1.12.2 Date: Thu, 07 Jun 2018 07:22:32 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: keep-alive 1 curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2 12132 nginx
如果是未定义的Nginx变量,是无法直接在Lua中进行读取的。而且有些变量只能读取,无法进行修改,如$query_string、$arg_PARAMETER和$testnginx.com/test?=12132&a=2&b=c&dd‘ HTTP/1.1 200 OK Server: nginx/1.12.2 Date: Fri, 08 Jun 2018 07:46:38 GMT Content-Type: application/octet-stream Transfer-Encoding: chunked Connection: keep-alive Header name:host value: testnginx.com Header name:accept value: */* Header name:user-agent value: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2 testnginx.com

