lua脚本拓展nginx功能

news/2024/7/6 4:36:21

文章目录

  • 一、nginx介绍
    • 1、定义
    • 2、优点
    • 3、使用场景
  • 二、lua介绍
    • 1、定义
    • 2、优点
    • 3、使用场景
  • 三、nginx中使用lua
  • 四、lua API介绍
  • 五、demo举例

一、nginx介绍

1、定义

Nginx 作为一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。

2、优点

占用内存少,稳定性高、模块化

3、使用场景

网页服务器、反向代理服务器以及电子邮件(IMAP/POP3)代理服务器,高并发大流量站点常用来做接入层的负载均衡,还有非常常见的用法是作为日志采集服务器等。

二、lua介绍

1、定义

是一个简洁、轻量、可扩展的脚本语言

2、优点

轻量级、可拓展、高性能、可移植性

3、使用场景

在很多时候,我们可以将Lua直接嵌入到我们的应用程序中,如游戏、监控服务器等。这样的应用方式对于程序的最终用户而言是完全透明的。

将Lua视为一种独立的脚本语言,通过它来帮助我们完成一些软件产品的辅助性工具的开发。

三、nginx中使用lua

ngx_lua_module 是一个nginx http模块,它把 lua 解析器内嵌到 nginx,用来解析并执行lua 语言编写的网页后台脚本。

下载最新的lua-nginx-module 模块

GitHub地址:https://github.com/openresty/lua-nginx-module/tags

重新编译nginx。

四、lua API介绍

指令所处处理阶段使用范围解释
init_by_lua; init_by_lua_fileloading-confighttpnginx Master进程加载配置时执行;通常用于初始化全局配置/预加载Lua模
init_worker_by_lua; init_worker_by_lua_filestarting-workerhttp每个Nginx Worker进程启动时调用的计时器,如果Master进程不允许则只会在init_by_lua之后调用;通常用于定时拉取配置/数据,或者后端服务的健康检查
set_by_lua; set_by_lua_filerewriteserver,server if,location,location if设置nginx变量,可以实现复杂的赋值逻辑;此处是阻塞的,Lua代码要做到非常快;
rewrite_by_lua; rewrite_by_lua_filerewrite tailhttp,server,location,location ifrrewrite阶段处理,可以实现复杂的转发/重定向逻辑;
access_by_lua; access_by_lua_fileaccess tailhttp,server,location,location if请求访问阶段处理,用于访问控制content_by_lua; content_by_lua_file
header_filter_by_lua; header_filter_by_lua_fileoutput-header-filterhttp,server,location,location if设置header和cookie信息
body_filter_by_lua; body_filter_by_lua_fileoutput-body-filterhttp,server,location,location if对响应数据进行过滤,比如截断、替换
log_by_lua; log_by_lua_fileloghttp,server,location,location iflog阶段处理,比如记录访问量/统计平均响应时间

五、demo举例

upstream kurento {
server 127.0.0.1:8443;
server 127.0.0.1:7443;
}

server {
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
    server_name slive.xxwolo.com;

    lua_need_request_body on;
    listen 443 ssl;
        ssl_certificate     /usr/local/openresty/nginx/ca/1_xxwolo.com_bundle.crt;
        ssl_certificate_key /usr/local/openresty/nginx/ca/2_xxwolo.com.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;

        location /call {
            proxy_pass http://127.0.0.1:8443;
	    #set $backend  '';
            #rewrite_by_lua_file   /usr/local/openresty/nginx/conf/vhosts/test.lua;
	    #proxy_pass http://$backend;	    
	    #content_by_lua_file   /usr/local/openresty/nginx/conf/vhosts/test.lua;

	    #proxy_pass http://kurento;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header X-Real-IP $remote_addr;
        }

        location /frist {
            proxy_pass http://127.0.0.1:8443;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header X-Real-IP $remote_addr;
        }

        location /second {
            proxy_pass http://127.0.0.1:7443;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header X-Real-IP $remote_addr;
        }

        location / {
            proxy_buffer_size 128k;
            proxy_buffers   32 128k;
            proxy_busy_buffers_size 256k;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            #proxy_pass http://localhost:8443;
	    proxy_pass http://kurento;
        }

    	location /call_2 {
            #default_type 'text/html';
            #lua_code_cache on;
         content_by_lua_block {
             ngx.req.read_body()
              local data = ngx.req.get_body_data()
               ngx.say(data)
         }
            #content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/print.lua;

            #proxy_http_version 1.1;
            #proxy_set_header Upgrade $http_upgrade;
            #proxy_set_header Connection "Upgrade";
            #proxy_set_header X-Real-IP $remote_addr;

    	}
	
        location /register {
            #default_type 'text/html';
            lua_code_cache on;
            content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/register.lua;
        }

        location /createRoom {
            default_type 'text/html';
            lua_code_cache on;
            content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/createRoom.lua;
        }

        location /addRoom {
            default_type 'text/html';
            lua_code_cache on;
            content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/addRoom.lua;
        }

        location /delRoom {
            default_type 'text/html';
            lua_code_cache on;
            content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/delRoom.lua;
        }

        location /getRoom {
            default_type 'text/html';
            lua_code_cache on;
            content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/getRoom.lua;
        }
}

createRoom.lua 的实现如下:

local function close_redis(red)  
    if not red then  
        return  
    end  
    local ok, err = red:close()  
    if not ok then  
        ngx.say("close redis error : ", err)  
    end  
end  
  
local redis = require("resty.redis")  
  
--创建实例  
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 

-- 验证密码
local res, err = red:auth("123456")
if not res then
    ngx.say("failed to authenticate: ", err)
    return
end

---- 验证获取key
--local ret, err = red:get("11111111")
--if not ret or ret == ngx.null or ret == nil then
--    -- 从zset中,移除,如果key不存在,则忽略
--    ngx.log("lua:移除过期key:")
--    close_redis()
--end
--ngx.say("lua:获取得结果为:", ret);
--close_redis()

-- 读取缓存并打印
local resp, err = red:zrangebyscore("test_zset", 0, 100000)
if not resp then
    ngx.say("get msg error : ", err)
    return close_redis(red)
end

--得到的数据为空处理
if resp == nil then
    ngx.say("lua: 可用服务器列表为空 : ", resp)
    return close_redis(red)
end

-- 判断数据是否过期,如果过期,删除重新获取,直到满足条件
local retVal
for key, value in ipairs(resp)
do
    ngx.log(ngx.ERR, key, value)
    local ret, err = red:get(value)
    if not ret or ret == nil or ret == ngx.null then
        -- 从zset中,移除,如果key不存在,则忽略
        ngx.log(ngx.ERR, value)
        red:zrem("test_zset", value)
    else
        retVal = value
        break
    end

    -- 重新获取resp
    resp, err = red:zrangebyscore("test_zset", 0, 100000)
    if not resp then
        ngx.say("get msg error : ", err)
        return close_redis(red)
    end
end

ngx.say("lua: 可用服务器的userID为 : ", retVal)
close_redis(red)  


http://www.niftyadmin.cn/n/3656138.html

相关文章

应用软件的组合技术:用XML描述你的框架(一)

应用软件的组合技术:用XML描述你的框架(一)第一次创建窗口对象是在Turbo C 2.0流行的时代完成的,至今还对操作VGA之类的代码留有印象,那个时代的编程与今天完全不同,1993年我开始接触WinSDK,当时…

springboot 事务管理

很多操作数据库的工具可以保证事务性,这里不讲。 这里讲的是,业务逻辑相关的东西,举例:你更新表A中的字段status,同时希望改变表B中的status字段,如果中间更新失败,则都不更新。 首先在应用类上…

最早的Tangram预览

最早的Tangram预览几天前与好友在msn上聊天,朋友给我一个惊喜,他提供给我2001年我发布的Tangram相关的信息,这些已经迷失的东西,看起来十分亲切,原始地址是http://www.vchelp.net:9090/dtool/submit/vdd_pa.htm&#x…

Tangram商业版本预览(二):Tabbed MDI 界面

Tangram商业版本预览(二):Tabbed MDI 界面 Tangram商业版本的目标是允许用户不用写程序代码,直接用XML描述直接得到商业质量的、高度可定制化的软件框架,事实上,软件框架部分代码基本与软件的功能是不相关的,如同高档写字楼一样&…

mongodb 聚合 按月分组统计

需求 先说下我的需求:查询用户每个月发布文章的天数,并以列表的形式返回。 举例:某用户在2020年12月份12号、8号、15号、22号曾经发布过文章,把所有发布文章的日期在数组中返回。 实现 以下是使用mongodb聚合实现命令。 [{$ma…

Tangram商业版本预览(一)

Tangram商业版本预览(一)Tangram商业版本计划于最近交付,其主要特点是包含其他版本的全部功能之外,提供一个高质量的UI定制能力,内置的Skin引擎支持多达2000多种流行的Skin,同时可以提供Microsoft Office系…

can‘t convert from BSON type long to Date

{$project: {year: {$year: "$createTime"},_id: 1,createTime: 1} }以上语句在查询mongodb时报错:cant convert from BSON type long to Date,截图如下: 原因:数据库存储的createTime为long类型,而project语句需要一个date类型&a…