ngx_lua配置及应用

一、说明

这里不对lua语言本身及其编译器运行环境等做介绍,以下所有介绍前提对lua相关有所了解。

二、ngx_lua介绍

原理

ngx_lua将Lua嵌入Nginx,可以让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求。Lua内建协程,这样就可以很好的将异步回调转换成顺序调用的形式。ngx_lua在Lua中进行的IO操作都会委托给Nginx的事件模型,从而实现非阻塞调用。开发者可以采用串行的方式编写程序,ngx_lua会自动的在进行阻塞的IO操作时中断,保存上下文;然后将IO操作委托给Nginx事件处理机制,在IO操作完成后,ngx_lua会恢复上下文,程序继续执行,这些操作都是对用户程序透明的。

每个NginxWorker进程持有一个Lua解释器或者LuaJIT实例,被这个Worker处理的所有请求共享这个实例。每个请求的Context会被Lua轻量级的协程分割,从而保证各个请求是独立的。

ngx_lua采用“one-coroutine-per-request”的处理模型,对于每个用户请求,ngx_lua会唤醒一个协程用于执行用户代码处理请求,当请求处理完成这个协程会被销毁。每个协程都有一个独立的全局环境(变量空间),继承于全局共享的、只读的“comman data”。所以,被用户代码注入全局空间的任何变量都不会影响其他请求的处理,并且这些变量在请求处理完成后会被释放,这样就保证所有的用户代码都运行在一个“sandbox”(沙箱),这个沙箱与请求具有相同的生命周期。

得益于Lua协程的支持,ngx_lua在处理10000个并发请求时只需要很少的内存。根据测试,ngx_lua处理每个请求只需要2KB的内存,如果使用LuaJIT则会更少。所以ngx_lua非常适合用于实现可扩展的、高并发的服务。

协程

协程类似一种多线程,与多线程的区别有:

  1. 协程并非os线程,所以创建、切换开销比线程相对要小。
  2. 协程与线程一样有自己的栈、局部变量等,但是协程的栈是在用户进程空间模拟的,所以创建、切换开销很小。
  3. 多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协程间协作的关系,只有当一个协程主动放弃执行权,另一个协程才能获得执行权,所以在某一瞬间,多个协程间只有一个在运行。
  4. 由于多个协程时只有一个在运行,所以对于临界区的访问不需要加锁,而多线程的情况则必须加锁。
  5. 多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的。

Nginx的每个Worker进程都是在epoll或kqueue这样的事件模型之上,封装成协程,每个请求都有一个协程进行处理。这正好与Lua内建协程的模型是一致的,所以即使ngx_lua需要执行Lua,相对C有一定的开销,但依然能保证高并发能力。

二、ngx_lua安装

Nginx中安装ngx_lua需要安装LuaJIT,ngx_devel_kit,ngx_lua等安装文件,我们这里用的OpenResty,内部已经集成ngx_lua,无需再安装任何模块。

三、ngx_lua用法

嵌套lua脚本

location /lua {
set $test "hello, world";
content_by_lua ‘
    ngx.header.content_type = "text/plain";
    ngx.say(ngx.var.test);
‘;
}

$ curl ‘http://134.32.28.134:8888/lua‘,输出 hello, world。

include lua文件

Nginx中include lua的脚本文件方式,如:

 location /mytest {
      content_by_lua_file conf/alcache.lua;
 }

其中在alcache.lua中编写lua脚本即可。

四、实际运用中通过lua结合分布式缓存对session的处理

这里redis与memcache的支持不是调用Nginx自带redis与memcache模块,都是调用OpenResty内部集成的第三方模块

nginx.conf部分配置

location /login {
    content_by_lua_file conf/alcache.lua;
}

alcache.lua配置

local key = tostring(ngx.var.arg_username)
local val = tostring(ngx.var.arg_password)
local passLogin = tostring(ngx.var.arg_passLoginFlag)
local flags = tostring(ngx.var.arg_flags or 0)
local exptime = tostring(ngx.var.arg_exptime or 0)
local sessionId  = tostring(ngx.var.cookie_JSESSIONID)
ngx.say("sessionId:",sessionId)
ngx.say("key:",key)
ngx.say("val:",val)
if (key == nil and val == nil)  then return end
--if (passLogin == nil or sessionId == nil)  then return end
local memcached = require("resty.memcached")
--local redis = require("resty.redis")
local cache,err = memcached:new()
--local cache,err = redis.new()
if not cache then
        ngx.say("failed to instantiate cache: ",err)
        return
end
cache:set_timeout(1000)
local ok,err = cache:connect("134.32.28.134",11211)
--local ok,err = cache:connect("134.32.28.134",6379)
if not ok then
        ngx.say("failed to connect: ",err)
        return
end
local res,flags,err = cache:get(key)
if err then
        ngx.say("failed to get ",key," : ",err)
        return
end
if res and tostring(res) ~= sessionId then
        cache:delete(key)
        cache:set(key,sessionId,exptime,flags)
else
                cache:set(key,sessionId,exptime,flags)
end
local ok, err = cache:close()
                if not ok then
            ngx.say("failed to close:", err)
        return
end
local url = ngx.var.uri
local res = ngx.location.capture("/proxy")
时间: 2024-12-17 05:18:22

ngx_lua配置及应用的相关文章

【记录】ngx_lua_waf安装记录

参考: http://www.ttlsa.com/nginx/nginx-modules-ngx_lua/ https://github.com/loveshell/ngx_lua_waf 1.安装 LuaJIT 2. 安装nginx 3.  安装ngx_lua模块 4.  安装ngx_lua_waf模块. 1.  安装LuaJIT wget http://luajit.org/download/LuaJIT-2.1.0-beta2.tar.gz tar –zxf LuaJIT-2.1.0-be

nginx插件ngx_lua

ngx_lua是淘宝的维护的产品,真心不错.配置文件包含可以做很多事情的lua脚本. 公司有个产品对注册的广告盒子进行反向代理,这样可以在盒子上做很多事情:和服务器通信,远程控制盒子等等.nginx反向代理这些盒子,都是在nginx的配置文件里边配置的.这个配置是要用程序进行生成.越来越多的程序没办法安置了,越来越多.终于在配置文件超过了260多个的时候,出现了超出了bucket....这又要修改其他的配置文件.这没个头了... 推荐使用配置嵌入lua脚本,有什么好处呢?反向代理内容可以放在re

ngx_lua 模块安装

一.使用环境 1.Nginx v1.11.2 2.Lua jit v2.0.4 3.ngx_lua_module v0.10.8 4.NDK v0.3.0 注:目前ngx_lua模块对Nginx支持版本最高为(1.11.2).文章时间(2017年4月24日16:07:36) 二.相关软件下载地址 1.Nginx [http://nginx.org/] 2.Lua Jit [http://luajit.org/download.html] 3.ngx_lua_module [https://git

ngx_lua应用最佳实践

引子: 以下文字,是UPYUN系统开发工程师timebug在SegmentFault D-Day南京站技术沙龙上所做分享的内容要义提炼,主题为UPYUN系统开发团队在进行业务逻辑由C模块到ngx_lua的迁移过程中产生的心得体会,以及在NGINX上基于ngx_lua的方面的最佳实践方案. Upyun公众号:upaiyun --------------------------------------------------------------------- ngx_lua 是一个NGINX的第

ngx_lua实现登录逻辑

最近在公司做一个简单的portal,本来很简单的,只用ngx_lua就可以实现所有的业务逻辑,不需要upstream上游服务.但被要求接入公司内部的用户校验系统,说白了就是一个登录过程,只允许公司内部的用户可以登录访问. 公司内部有一整套组件,只要在业务代码里嵌入改组件,就能自动检测用户是否已经登录.或session是否过期,是则跳转到登录界面,用户输入密码验证后,重新跳转会原始访问的页面. 但公司提供的组件都是基于常用的业务语言的,如php.java,我也不想再加上这些玩意,于是考虑用ngx_

NGINX安全防护之基于ngx_lua的web应用防火墙

NGINX安全防护 ngx_lua_waf安装说明文档 作者github地址: https://github.com/loveshell/ngx_lua_waf 转自作者说明文档: ngx_lua_waf是我一个基于ngx_lua的web应用防火墙. 代码很简单,开发初衷主要是使用简单,高性能和轻量级. 现在开源出来.其中包含我们的过滤规则.如果大家有什么建议和想fa,欢迎和我一起完善.   用途: 用于过滤post,get,cookie方式常见的web攻击 防止sql注入,本地包含,部分溢出,

Nginx+Lua+Redis配置

想在Nginx上开发具有这样功能的一个转发模块,外部转发策略控制服务器将一些指定的URL发送给数据库,Nginx读取数据库中的URL列表,将列表指定的这些URL转发到特定的缓存代理服务器上,其他非数据库URL列表中的URL请求直接通过Nginx转发到出口网关上.实际上以上的功能就是很多网站利用Nginx做负载均衡时的实现的七层转发功能,不太一样的是,我想加一个外部的转发策略控制服务器将一些实时的URL列表发送给Nginx,这样如果这些URL信息是根据大数据处理结果统计出的最高热点访问URL,就可

nginx使用ngx_lua访问后端Thrift-Server实现和介绍

背景 随着openresty的出现,让nginx使用lua解决一些业务的能力大幅度提高,ngx_lua可以使用nginx自生的基于事件驱动的IO模型,和后端的存储,业务等系统实现非阻塞的连接交互. 如何使用ngx_lua连接后端的Thrift-Server呢? 基于这个需求,本人为ngx_lua做了一下增强. 增强后的业务架构图 前端使用http对外提供服务,将请求的数据调用ngx_lua逻辑,使用定义好的Thrift的IDL文件生成lua代码,调用Thrift的服务,实现业务逻辑. 开源实现g

nginx防止DDOS攻击配置

防御DDOS是一个系统工程,攻击花样多,防御的成本高瓶颈多,防御起来即被动又无奈.DDOS的 特点是分布式,针对带宽和服务攻击,也就是四层流量攻击和七层应用攻击,相应的防御瓶颈四层在带宽,七层的多在架构的吞吐量.对于七层的应用攻击,我们还 是可以做一些配置来防御的,例如前端是Nginx,主要使用nginx的http_limit_conn和http_limit_req模块来防御. ngx_http_limit_conn_module 可以限制单个IP的连接数,ngx_http_limit_req_